拷贝构造函数和拷贝赋值函数是一对很容易混淆的概念,下面根据我自己的理解为大家梳理一下。由于我也只是个新手,难免会有理解错误,还请大家指正。
一.拷贝构造函数
拷贝构造函数是一种特殊的构造函数,其特殊之处就在于它是用一个已知的类对象来初始化新定义的类对象。
拷贝构造函数分为深拷贝和浅拷贝。
1.浅拷贝:默认的拷贝构造函数(包括通过“=”来实现对象复制的)都执行的是浅拷贝。浅拷贝构造函数会将拷贝对象初始化为和源对象一样的对象,但是当类中有指针或引用类型的成员时,在对象被析构时将发生错误。原因是经过浅拷贝后,源对象和拷贝对象中的指针成员将指向同一片内存,在两个对象通过析构函数被撤销时,这片内存将被释放两次,从而发生错误。为了解决这问题,便有了深拷贝。
2.深拷贝一般都是自己编写的拷贝构造函数。一般的定义形式如下,详细实现参照博文http://blog.youkuaiyun.com/cjy0000/article/details/35321145
A(const A &a){}
深拷贝很好了解决了上面提到的问题,通过调用深拷贝构造函数可以为拷贝对象重新动态分配相应的内存空间,这样一来,源对象的指针成员就指向源对象的内存空间,而拷贝对象的指针成员指向拷贝对象的内存空间,在调用析构函数释放内存时,不会发生错误。
二.拷贝赋值函数
拷贝赋值函数和拷贝构造函数很像,但是拷贝赋值函数是用一个源对象来修改一个已经存在的对象。
拷贝赋值函数可以分为默认拷贝赋值函数和自己编写的拷贝赋值函数两种。
1.默认的拷贝赋值函数不用我们自己编写,而是通过“=”直接调用。
A a(初始化列);
A b(初始化列);
a = b; //拷贝赋值函数
A c = a; //拷贝构造函数(浅拷贝)
它存在着跟浅拷贝一样的问题,即当类中有指针或引用类型的成员时,在对象被析构时将发生错误。原因是经过浅拷贝后,源对象和拷贝对象中的指针成员将指向同一片内存,在两个对象通过析构函数被撤销时,这片内存将被释放两次,从而发生错误。为了解决这问题,我们必须自己编写相应的拷贝赋值函数。
2.自己编写的拷贝赋值函数
String& String::operator=(const String& other)
{
if(this != &other)//检查自赋值
{
char *temp = new char[strlen(other.m_data) + 1];//分配新内存
atrcpy(temp,other.m_data);//复制数据
delete [] m_data;
m_data = temp;
m_size = strlen(other.m_data);
}
return *this;
}
3.派生类的拷贝赋值函数
派生类的拷贝赋值函数还需要给基类成员进行赋值,所以普通的拷贝赋值函数无法实现其需求,所以派生类的拷贝构造函数需要注意,详文请看下面链接:
http://blog.sina.com.cn/s/blog_72ed42d40100tnir.html