MFC中CArray类的成员函数SetSize中的两个参数的解释

作者&投稿:黎话 (若有异议请与网页底部的电邮联系)
MFC列表中SetItemData里面的两个参数怎么解释~

就是为特定的项设定一个数值,一般用不到,但是有时候也会用到,比如我们有时候除了在列表里面插入一项以外,还需要设定与该项一个有关的数值。那么这个就很有用,这个功能平常使用的不多。

CArray的 用法

需要包含的头文件
CArray类支持与C arrays相似的数组,但是必要时可以动态压缩并扩展。数组索引从0开始。可以决定是固定数组上界还是允许当添加元素时扩展当前的边界。内存对上界是连续地分配空间,甚至一些元素可为空。
和C arrays一样,CArray索引元素的访问时间是不变的,与数组大小无关。
提示:
在使用一个数组之前,使用SetSize建立它的大小和为它分配内存。如果不使用SetSize,则为数组添加元素就会引起频繁地重新分配和拷贝。频繁地重新分配和拷贝不但没有效率,而且导致内存碎片。
如果需要一堆数组中的个别数据,必须设置CDumpContext对象的深度为1或更大。
此类的某成员函数调用全局帮助函数,它必须为CArray的大多数使用而定制。请参阅宏和全局量部分中的“类收集帮助器”。
当从一个CArray对象中移去元素时,帮助函数DestructElements被调用。
当添加元素时,帮助函数ConstructElements被调用。
数组类的派生与列表的派生相似。
MFC提供了一套模板库,来实现一些比较常见的数据结构如Array,List,Map。CArray即为其中的一个,用来实现动态数组的功能。CArray是从CObject派生,有两个模板参数,第一个参数就是CArray类数组元素的变量类型,后一个是函数调用时的参数类型。有一个类 class Object,要定义一个Object的动态数组,那么可以用以下两种方法:
CArray Var1;
CArray Var2;
Var2的效率要高。
先了解一下CArray中的成员变量及作用。TYPE* m_pData; // 数据保存地址的指针
int m_nSize; // 用户当前定义的数组的大小
int m_nMaxSize; // 当前实际分配的数组的大小
int m_nGrowBy; // 分配内存时增长的元素个数
构造函数,对成员变量进行了初始化。
CArray::CArray()
{
m_pData = NULL;
m_nSize = m_nMaxSize = m_nGrowBy = 0;
}
SetSize成员函数是用来为数组分配空间的。SetSize的函数定义如下:
void SetSize( int nNewSize, int nGrowBy = -1 );
nNewSize 指定数组的大小
nGrowBy 如果需要增加数组大小时增加的元素的个数。
对SetSize的代码,进行分析。
void CArray::SetSize(int nNewSize, int nGrowBy)
{
if (nNewSize == 0)
{
// 第一种情况
// 当nNewSize为0时,需要将数组置为空,
// 如果数组本身即为空,则不需做任何处理
// 如果数组本身已含有数据,则需要清除数组元素
if (m_pData != NULL)
{
//DestructElements 函数实现了对数组元素析构函数的调用
//不能使用delete m_pData 因为我们必须要调用数组元素的析构函数
DestructElements(m_pData, m_nSize);
//现在才能释放内存
delete[] (BYTE*)m_pData;
m_pData = NULL;
}
m_nSize = m_nMaxSize = 0;
}
else if (m_pData == NULL)
{
// 第二种情况
// 当m_pData==NULL时还没有为数组分配内存
//首先我们要为数组分配内存,sizeof(TYPE)可以得到数组元素所需的字节数
//使用new 数组分配了内存。注意,没有调用构造函数
m_pData = (TYPE*) new BYTE[nNewSize * sizeof(TYPE)];
//下面的函数调用数组元素的构造函数
ConstructElements(m_pData, nNewSize);
//记录下当前数组元素的个数
m_nSize = m_nMaxSize = nNewSize;
}
else if (nNewSize <= m_nMaxSize)
{
// 第三种情况
// 这种情况需要分配的元素个数比已经实际已经分配的元素个数要少
if (nNewSize > m_nSize)
{
// 需要增加元素的情况
// 与第二种情况的处理过程,既然元素空间已经分配,
// 只要调用新增元素的构造函数就Ok
ConstructElements(&m_pData[m_nSize], nNewSize-m_nSize);
}
else if (m_nSize > nNewSize)
{
// 现在是元素减少的情况,我们是否要重新分配内存呢?
// No,这种做法不好,后面来讨论。
// 下面代码释放多余的元素,不是释放内存,只是调用析构函数
DestructElements(&m_pData[nNewSize], m_nSize-nNewSize);
}
m_nSize = nNewSize;
}
else
{
//这是最糟糕的情况,因为需要的元素大于m_nMaxSize,
// 意味着需要重新分配内存才能解决问题
// 计算需要分配的数组元素的个数
int nNewMax;
if (nNewSize < m_nMaxSize + nGrowBy)
nNewMax = m_nMaxSize + nGrowBy;
else
nNewMax = nNewSize;
// 重新分配一块内存
TYPE* pNewData = (TYPE*) new BYTE[nNewMax * sizeof(TYPE)];
//实现将已有的数据复制到新的的内存空间
memcpy(pNewData, m_pData, m_nSize * sizeof(TYPE));
// 对新增的元素调用构造函数
ConstructElements(&pNewData[m_nSize], nNewSize-m_nSize);
//释放内存
delete[] (BYTE*)m_pData;
//将数据保存
m_pData = pNewData;
m_nSize = nNewSize;
m_nMaxSize = nNewMax;
}
}
下面是ConstructElements函数的实现代码template
AFX_INLINE void AFXAPI ConstructElements(TYPE* pElements, int nCount)
{
// first do bit-wise zero initialization
memset((void*)pElements, 0, nCount * sizeof(TYPE));
for (; nCount--; pElements++)
::new((void*)pElements) TYPE;
}
ConstructElements是一个模板函数。对构造函数的调用是通过标为黑体的代码实现的。可能很多人不熟悉new 的这种用法,它可以实现指定的内存空间中构造类的实例,不会再分配新的内存空间。类的实例产生在已经分配的内存中,并且new操作会调用对象的构造函数。因为vc中没有办法直接调用构造函数,而通过这种方法,巧妙的实现对构造函数的调用。
再来看DestructElements 函数的代码template
AFX_INLINE void AFXAPI DestructElements(TYPE* pElements, int nCount)
{
for (; nCount--; pElements++)
pElements->~TYPE();
}
DestructElements函数同样是一个模板函数,实现很简单,直接调用类的析构函数即可。
如果定义一个CArray对象 CArray myObject ,对myObject就可象数组一样,通过下标来访问指定的数组元素。
CArray[]有两种实现,区别在于返回值不同。
template
AFX_INLINE TYPE CArray::operator[](int nIndex) const
{ return GetAt(nIndex); }
template
AFX_INLINE TYPE& CArray::operator[](int nIndex)
{ return ElementAt(nIndex); }
前一种情况是返回的对象的实例,后一种情况是返回对象的引用。分别调用不同的成员函数来实现。
TYPE GetAt(int nIndex) const
{ ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
TYPE& ElementAt(int nIndex)
{ ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
除了返回值不同,其它都一样.
CArray arrInt;
arrInt.SetSize(10);
int n = arrInt.GetAt(0);
int& l = arrInt.ElementAt(0);
cout << arrInt[0] <<endl;
n = 10;
cout << arrInt[0] <<endl;
l = 20;
count << arrInt[0] << endl;
结果会发现,n的变化不会影响到数组,而l的变化会改变数组元素的值。实际即是对C++中引用运算符的运用。
CArray下标访问是非安全的,它并没有超标预警功能。虽然使用ASSERT提示,但下标超范围时没有进行处理,会引起非法内存访问的错误。
Add函数的作用是向数组添加一个元素。下面是它的定义: int CArray::Add(ARG_TYPE newElement).Add函数使用的参数是模板参数的二个参数,也就是说,这个参数的类型是我们来决定的,可以使用Object或Object&的方式。熟悉C++的朋友都知道,传引用的效率要高一些。如果是传值的话,会在堆栈中再产生一个新的对象,需要花费更多的时间。
template
AFX_INLINE int CArray::Add(ARG_TYPE newElement)
{
int nIndex = m_nSize;
SetAtGrow(nIndex, newElement);
return nIndex;
}
它实际是通过SetAtGrow函数来完成这个功能的,它的作用是设置指定元素的值。
template
void CArray::SetAtGrow(int nIndex, ARG_TYPE newElement)
{
if (nIndex >= m_nSize)
SetSize(nIndex+1, -1);
m_pData[nIndex] = newElement;
}
SetAtGrow的实现也很简单,如果指定的元素已经存在,就把改变指定元素的值。如果指定的元素不存在,也就是 nIndex>=m_nSize的情况,就调用SetSize来调整数组的大小
首先定义
CArray arryPChar;
这里以定义char*的为例子。
接下来我们来熟悉CArray这个类里的函数。
INT_PTR GetCount() const;
获得当前这个数组有多少个元素。
void SetSize(INT_PTR nNewSize, INT_PTR nGrowBy = -1);
设置数组的大小。
TYPE& GetAt(INT_PTR nIndex);
void SetAt(INT_PTR nIndex, ARG_TYPE newElement);
获得/设置序列的元素
INT_PTR Add(ARG_TYPE newElement);
在数组的末尾添加一个元素,数组的长度加1。如果之前使用SetSize是nGrowBy大于1,则内存按照nGrowBy增加。函数返回newElement的数组元素索引
void RemoveAt(INT_PTR nIndex, INT_PTR nCount = 1);
从指定的nIndex位置开始,删除nCount个数组元素,所有元素自动下移,并且减少数组的上限,但是不释放内存。这里我们自己手动的申请的就必须自己释放。new对应delete相信大家都知道的。
void RemoveAll();
从数组中移除素有的元素,如果数组为空,该行数也起作用。
INT_PTR Append(const CArray& src);
将同个类型的一个数组A附加到本数组的尾部,返回A第一数组元素在本数组的索引。
void InsertAt(INT_PTR nIndex, ARG_TYPE newElement, INT_PTR nCount = 1);
void InsertAt(INT_PTR nStartIndex, CArray* pNewArray);
在指定的nIndex或者nStartIndex位置插入nCount个newElement数组元素或者pNewArray数组
下面是我应用的实例:
view plaincopy to clipboardprint?
CArray arrPChar;
//初始化元素
arrPChar.SetSize(10);
for (int i=0;i<10;i++)
{
char *aChar=new char[10];
strcpy_s(aChar,10,"hello arr");
arrPChar.SetAt(i,aChar);
}
//在数组的末尾插入一个元素
char *bChar = new char[10];
strcpy_s(bChar,10,"asdfefdsd");
arrPChar.Add(bChar);
//在索引2的位置插入一个元素,即在第三位插入一个元素
char *cChar=new char[5];
strcpy_s(cChar,5,"aidy");
arrPChar.InsertAt(2,cChar);
for (int j=0;j<arrPChar.GetCount();j++)
{
TRACE("%d,%s
",j,arrPChar.GetAt(j));
}
//删除数组里的所有元素,要释放内存,如果单单Remove的话则内存不会被释放
//这里因为使用RemoveAll的话内存无法被释放,所以没有给实例。
int count = arrPChar.GetCount();
for (int k=0; k<count; k++)
{
char *dChar=arrPChar.GetAt(0);
arrPChar.RemoveAt(0);
delete dChar;
}



分配至少含32个元素的内存空间,如果后续有新元素需加入myArray阵列,可扩展到128个元素内存空间。


请问电荷量单位fC和C之间怎么换算?
C代表库伦(国际制基本导出单位),f为femto(国际制词头),读“飞”,与飞秒单位类同。一般f为小写,C为大写。

STEP7程序里,(举个例子)看了FC101里边有个点是“1”。但是打开FC101这 ...
108 0x006c 磁碟正在使用中或被锁定。 109 0x006d pipe 已经中止。 110 0x006e 系统无法开启指定的 装置或档案。 111 0x006f 档名太长。 112 0x0070 磁碟空间不足。 113 0x0071 没有可用的内部档案识别字。 114 0x0072 目标内部档案识别字不正确。 117 0x0075 由应用程式所执行的 ioctl 呼叫 不正确。

生理学中 缩写FC指什么
是说的FC受体么——为对免疫球蛋白Fc部分c末端的受体。对具有该受体的细胞,通过抗体与抗原结合时,细胞将发挥如下的特有机能:(1)原噬菌体对IgG,占多形核白细胞大部分的嗜中性细胞对IgG、IgA具有Fc受体,通常通过与抗原结合的抗体以及有时与游离的抗体(嗜细胞性抗体)结合来捕捉抗原,并经吞噬...

请教,混凝土轴心抗压强度Fc与标号C多少的关
砼轴心抗压标准值是Cx的X值的66.7%。如:C15的是15×67%=10,C25的是25×66.7%=16.7.。。,你可验算一下其他标号,看看是不是。顺便说一下,设计值fc是标准值fck的71%左右。

经济学中关于fc的公式是什么意思
FC为固定成本FC=TC-VCFC=AFC×Q固定成本(又称固定费用)相对于变动成本,是指成本总额在一定时期和一定业务量范围内,不受业务量增减变动影响而能保持不变的成本。固定成本的特征在于它在一定时间范围和业务量范围内其总额维持不变,但是,相对于单位业务量而言,单位业务量所分摊(负担)的固定成本与业务...

空之轨迹SC中如何继承FC的存档?
普通版本:\\x0d\\x0a把FC的存档放在C:\\Users\\(你的用户名,例如Administrator)\\AppData\\Roaming\\falcom\\ed6\\\\x0d\\x0a这个路径中如果是中文版的系统则Users文件夹名字是“用户”\\x0d\\x0a如果中间有文件夹不存在就自己创建名字一定要一样\\x0d\\x0a\\x0d\\x0a如果SC是三豪版中文版,要继承FC...

建筑图纸中WC、 CC、 FC分别表示什么?
WC、CC、FC分别表示:沿楼板地面敷设、沿楼顶顶棚敷设、沿楼板地面敷设。具体情况:1、SC:焊接钢管 2、线管后面的CC、WC、FC,则是线管的敷设方式 3、CC:暗敷设在屋面或顶板内 4、WC:暗敷设在墙内 5、FC:地板或地面下敷设

足球队名中带有一个FC,是什么意思?
足球队名中带有一个FC,是football club的缩写,即足球俱乐部的意思。英国的足球俱乐部把FC放在俱乐部名字的后面,如切尔西足球俱乐部,英文全称为Chelsea Football Club。西班牙的足球俱乐部把FC放在俱乐部名字的前面,如巴塞罗那足球俱乐部,英文全称为Football Club Barcelona,简称巴萨(barça)。又如意甲...

请问什么是ST、 FC、 C、 AT?
答案:ST、STFC、C、和AT是不同的术语,分别有不同的含义。解释:1. **ST**:通常是"Structured Text"的缩写,是一种高级的程序设计语言,主要用于工业自动化和控制系统的开发。ST语言是IEC 61131-3标准的一部分,主要用于可编程逻辑控制器(PLC)的编程。2. **STFC**:没有通用的解释,可能是...

尾纤中SC、PC、LC、FC分别是什么头
其所采用的插针和套筒的尺寸是普通SC、FC等所用尺寸的一半,为1.25mm。这样可以提高光纤配线架中光纤连接器的密度。目前,在单模SFF方面,LC类型的连接器实际已经占据了主导地位,在多模方面的应用也增长迅速。 光纤连接器端面接触方式有PC、UPC、APC型三种。 <图略> PC——Physic Contact,原意是物理接触的意思,插针...

祁县18215937202: c++ MFC CArray类 成员函数 属性 -
姚娅灵芝: GetSize() 得到的是长度 GetCount() 得到的是个数

祁县18215937202: VC++MFC编程出错:关于CArray数组 -
姚娅灵芝: 你这个是CArray的嵌套, 外层CArray里的成员函数SetAtGrow用到了"="; 里层CArray类没有"="这个重载函数,所以你不能用"="赋值;例如:CArray <CString,CString&> a, b; a = b; 这是不对的.给你两种思路:1.重载CArray 里的"="函数.2.要不你改下 CArray <stepnc,stepnc&> nc;试试用指针代替:CArray <stepnc*,stepnc*> nc;

祁县18215937202: MFC CArray的使用方法 -
姚娅灵芝: MFC提供了一套模板库,来实现一些比较常见的数据结构如Array,List,Map.CArray即为其中的一个,用来实现动态数组的功能.CArray是从CObject派生,有两个模板参数,第一个参数就是CArray类数组元素的变量类型,后一个是函数调用时的参数类型.

祁县18215937202: Visual C++ 中CArry属于哪一个类 -
姚娅灵芝: CArray 是从CObject继承来的.这是MFC里边的一个类,查MSDN就可以查得到. 需要包含的头文件 CArray类支持与C arrays相似的数组,但是必要时可以动态压缩并扩展.数组索引从0开始.可以决定是固定数组上界还是允许当添加元素时扩展当前的边界.内存对上界是连续地分配空间,甚至一些元素可为空. 和CArray一样,CArray索引元素的访问时间是不变的,与数组大小无关.

祁县18215937202: MFC中的CArray函数中,有一个RemoveAll()操作. -
姚娅灵芝: RemoveAll清除所有元素,释放掉元素占据的内存,在添加新的元素之前,当然不能进行任何读取操作.

祁县18215937202: MFC C++ CArray类 -
姚娅灵芝: 清空所有 后果是对象里没有数据了 Removes all the elements from this array. If the array is already empty, the function still works.

祁县18215937202: 怎样在MFC里面添加一个类的成员函数 -
姚娅灵芝: 在CDialog1中包含CRubberbandView的头文件 在CDialog1的ONOK()函数中定义一个CRubberbandView的对象rb 调用函数 rb. bresenham 试下可以不

祁县18215937202: MFC中常用类,宏,函数介绍 -
姚娅灵芝: MFC中常用类,宏,函数介绍常用类CRect:用来表示矩形的类,拥有四个成员变量:top left bottom right.分别表是左上角和右下角的坐标.可以通过以下的方法构造:CRect( int l, int t, int r, int b ); 指明四个坐标CRect( const RECT& ...

祁县18215937202: MFC中全局函数怎么调用类的成员函数 -
姚娅灵芝: 类的成员函数只有该类的成员可以调用.类的静态成员变量只有该类才可以调用,类成员不能调用.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网