类对象之间的初始化是由类的拷贝构造函数完成的。它是一种特殊的构造函数,它的作用是用一个已知的对象来初始化另一个对象。如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝。
一、拷贝构造函数定义格式
类名::拷贝构造函数名(类名& 引用名)
例如:
Tdate ::Tdate(Tdate & d); //形参是一个对象的引用
CString( const CString & stringSrc ); //形参是一个const的对象引用
二、通常在下述三种情况下,需要用拷贝初始化构造函数:
1)明确表示由一个对象初始化另一个对象时;如Cdate day3(d1);
2)当对象作为函数实参传递给函数形参时;如fun(Cdate day);
3)当对象作为函数的返回值,创建一个临时对象时。
浅拷贝和深拷贝
浅拷贝只对对象数据成员进行简单的赋值复制操作,在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。
深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。下面举个深拷贝的例子。
#include "stdafx.h" #include <iostream> #include <string> #include <stdio.h> using namespace std; class CClass { public: CClass (char *cName="",int snum=0); ~CClass() {cout<<"析构班级:"<<pname<<endl; delete pname; } void Print(); private: char *pname; int num; }; CClass::CClass(char *cName,int snum) { int length = strlen(cName); pname = new char[length+1]; if (pname!=0) //pname!=NULL strcpy(pname,cName); num=snum; cout<<"创建班级:"<<pname<<endl; } void CClass::Print() { cout<<pname<<"班的人数为:"<<num<<endl; } int _tmain(int argc, _TCHAR* argv[]) { CClass c1("计算机061班,56); CClass c2 (c1); c1.Print(); c2.Print(); //system("pause"); return 0; }
c1、c2内存分配情况(深拷贝)
CClass(CClass &p); //自定义拷贝构造函数声明 //添加自定义拷贝构造函数 CClass::CClass(CClass &p) { pname = new char[strlen(p.pname )+1]; if (pname!=0) strcpy(pname,p.pname); num=p.num ; cout<<"创建班级的拷贝:"<<pname<<endl; }
运行结果:
创建班级:计算机061班
创建班级的拷贝:计算机061班
计算机061班班的人数为:56
计算机061班班的人数为:56
析构班级:计算机061班
析构班级:计算机061班
时间: 2024-10-14 06:25:39