|
重点:包含动态分配成员的类 应提供拷贝构造函数,并重载"="赋值操作符。 以下讨论中将用到的例子: class CExample { public: CExample(){pBuffer=NULL; nSize=0;} ~CExample(){delete pBuffer;} void Init(int n){ pBuffer=new char[n]; nSize=n;} private: char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源 int nSize; }; 这个类的主要特点是包含指向其他资源的指针。 pBuffer指向堆中分配的一段内存空间。 一、拷贝构造函数 int main(int argc, char* argv[]) { CExample theObjone; theObjone.Init40); //现在需要另一个对象,需要将他初始化称对象一的状态 CExample theObjtwo=theObjone; ... } 语句"CExample theObjtwo=theObjone;"用theObjone初始化theObjtwo。 其完成方式是内存拷贝,复制所有成员的值。 完成后,theObjtwo.pBuffer==theObjone.pBuffer。 即它们将指向同样的地方,指针虽然复制了,但所指向的空间并没有复制,而是由两个对象共用了。这样不符合要求,对象之间不独立了,并为空间的删除带来隐患。 所以需要采用必要的手段来避免此类情况。 回顾以下此语句的具体过程:首先建立对象theObjtwo,并调用其构造函数,然后成员被拷贝。 可以在构造函数中添加操作来解决指针成员的问题。 所以C++语法中除了提供缺省形式的构造函数外,还规范了另一种特殊的构造函数:拷贝构造函数,上面的语句中,如果类中定义了拷贝构造函数,这对象建立时,调用的将是拷贝构造函数,在拷贝构造函数中,可以根据传入的变量,复制指针所指向的资源。 拷贝构造函数的格式为:构造函数名(对象的引用) 提供了拷贝构造函数后的CExample类定义为: class CExample { public: CExample(){pBuffer=NULL; nSize=0;} ~CExample(){delete pBuffer;} CExample(const CExample&); //拷贝构造函数 void Init(int n){ pBuffer=new char[n]; nSize=n;} private: char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源 int nSize; }; CExample::CExample(const CExample& RightSides) //拷贝构造函数的定义 { nSize=RightSides.nSize; //复制常规成员 pBuffer=new char[nSize]; //复制指针指向的内容 memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char)); } 这样,定义新对象,并用已有对象初始化新对象时,CExample(const CExample& RightSides)将被调用,而已有对象用别名RightSides传给构造函数,以用来作复制。
|