1.相关概念
浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型), 拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。即默认拷贝构造函数只是对对象进行浅拷贝复制(逐个成员依次拷贝),即只复制对象空间而不复制资源。
一般情况下,只需使用系统提供的浅拷贝构造函数即可,但是,如果对象的数据成员包括指向堆空间的指针,就不能使用这种拷贝方式,因为两个对象都拥有同一个资源,对象析构时,该资源将经历两次资源返还,此时必须自定义深拷贝构造函数,为创建的对象分配堆空间,否则会出现动态分配的指针变量悬空的情况。
深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。
2.浅拷贝-shallow copy
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
using namespace std;
class MyString
{
public:
MyString(const char *str = "")
{
if(str == NULL)
{
data = new char[1];
data[0] = '\0';
}
else
{
data = new char[strlen(str)+1];
strcpy(data,str);
}
}
~MyString()
{
cout << "~MyString " << data << endl;
delete []data;
data = NULL;
}
public:
char* data;
};
int main()
{
MyString s1("hello");
MyString s2 = s1;
cout << "s1.data's address is " << (void*)(s1.data) << endl;
cout << "s2.data's address is " << (void*)(s2.data) << endl;
}
3.深拷贝-deep copy
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
using namespace std;
class MyString
{
public:
MyString(const char *str = "")
{
if(str == NULL)
{
data = new char[1];
data[0] = '\0';
}
else
{
data = new char[strlen(str)+1];
strcpy(data,str);
}
}
MyString(const MyString& s)
{
data = new char[strlen(s.data)+1];
strcpy(data,s.data);
}
MyString& operator=(const MyString& s)
{
if(this!= &s)
{
delete []data;
data = new char[strlen(s.data) + 1];
strcpy(data,s.data);
}
return *this;
}
~MyString()
{
cout << "~MyString " << data << endl;
delete []data;
data = NULL;
}
public:
char* data;
};
int main()
{
MyString s1("hello");
MyString s2 = s1;
cout << "s1.data's address is " << (void*)(s1.data) << endl;
cout << "s2.data's address is " << (void*)(s2.data) << endl;
MyString s3;
cout << "s3.data's address is " << (void*)(s3.data) << endl;
s3 = s2;
cout << "s3.data's address is " << (void*)(s3.data) << endl;
}