类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量,因此,类对象之间的复制较为复杂。
#include <iostream>
using namespace std;
class CExample
{
private:
int a;//成员变量
public:
CExample(int b)//构造函数
a=b;
void Show ()//成员函数
cout<<a<<endl;
};
int main()
{
CExample A(100);
CExample B=A;//调用默认的拷贝构造函数
B.Show ();//输出100
return 0;
}
系统为对象B分配了内存,并将对象A复制给对象B,此过程调用默认的拷贝构造函数(浅拷贝)
#include <iostream> using namespace std; class CExample { private: int a; public: CExample(int b)//构造函数 a=b; CExample(const CExample& C)//拷贝构造函数 a=C.a; void Show () cout<<a<<endl; }; int main() { CExample A(100); CExample B=A;//使用自定义的拷贝构造函数 B.Show ();//输出100 return 0; }
系统为对象B分配了内存,并将对象A复制给对象B,此过程调用自定义的拷贝构造函数(浅拷贝)
浅拷贝和深拷贝
在某些状况下,类内成员变量需要动态开辟堆内存,如果实行浅拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针。
深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源(堆,或者是其它系统资源);当这个类的对象发生复制过程的时候:
重新分配资源,这个过程就是深拷贝;
没有重新分配资源,就是浅拷贝。
#include <iostream>
using namespace std;
class CA
{
public:
CA(int b,char* cstr)//构造函数
{
a=b;//初始化成员变量a
str=new char[b];
//从cstr地址开始且含有null结束符的字符串复制到
//以str地址开始的字符串中
strcpy(str,cstr);
}
CA(const CA& C)//拷贝构造函数
{
a=C.a;
str=new char[a]; //深拷贝,重新分配资源
if(str!=0)
strcpy(str,C.str);
}
void Show()
cout<<str<<endl;
~CA()//析构函数
delete str;//释放分配的资源
private:
int a;
char *str;
};
int main()
{
CA A(10,"Hello!");
CA B=A;//调用自定义的拷贝构造函数
B.Show();//输出Hello!
return 0;
}
系统为对象B分配了内存,并将对象A复制给对象B,并为对象B重新分配了资源,此过程调用自定义的拷贝构造函数(深拷贝)