拷贝构造函数(深拷贝vs浅拷贝)
类对象之间的初始化是由类的拷贝构造函数完毕的。它是一种特殊的构造函数,它的作用是用一个已知的对象来初始化还有一个对象。假设在类中没有显式地声明一个拷贝构造函数。那么,编译器将会自己主动生成一个默认的拷贝构造函数,该构造函数完毕对象之间的位拷贝。位拷贝又称浅拷贝。
一、拷贝构造函数定义格式
类名::拷贝构造函数名(类名& 引用名)
比如:
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内存分配情况(深拷贝)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGF1dF96amI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
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班