浅拷贝 ##—–位拷贝
浅拷贝是将原始对象中的数据型字段拷贝到新对象中去,将引用型字段的“引用”复制到新对象中去,不把“引用的对象”复制进去,所以原始对象和新对象引用同一对象,新对象中的引用型字段发生变化会导致原始对象中的对应字段也发生变化。
- 概念:
将一个对象中的内容原封不动的拷贝到另一个对象中,多个对象共享同一个资源。
- 后果:
在销毁对象时一个资源被释放多次引起程序崩溃。
class String
{
public:
String(const char* pStr = "")
:_pStr(new char[strlen(pStr)+1])
{
strcpy(_pStr, pStr);
}
~String()
{
if (_pStr)
delete[] _pStr;
}
private:
char* _pStr;
};
void Test()
{
String s1("hello world");
//当类里面有指针对象时,拷贝构造和赋值运算符只进行值拷贝,
//两个对象共用同一块资源,对象销毁时程序会发生内存访问违规
String s2(s1);
}
深拷贝
深拷贝就是创建一个新的和原始字段的内容相同的字段,是两个一样大的数据段,所以两者的引用是不同的,之后的新对象中的引用型字段发生改变,不会引起原始对象中的字段发生改变。
实现String类的深拷贝传统写法:
class String
{
public:
String(const char *str = "")
{
if (NULL == str)
_str = "";
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
String(const String& str)
:_str(new char[strlen(str._str)+1])
{
strcpy(_str, str._str);
}
String& operator=(const String& str)
{
if (this != &str)
{
char* tmp = new char[strlen(str._str) + 1];
strcpy(tmp, str._str);
delete[] _str;
_str = tmp;
}
return *this;
}
~String()
{
if (_str)
{
delete[] _str;
}
}
private:
char *_str;
};
void TestString()
{
String s1("thanks");
String s2(s1);
String s3 = s2;
}
实现String类的深拷贝的现代写法:
class String
{
public:
String(const char *str = "")
{
if (NULL == str)
_str = "";
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
String(const String& str)
:_str(NULL)
{
String tmpStr(str._str);
swap(_str, tmpStr._str);
}
/* 第一种写法 */
/*String& operator=(const String& str)
{
if (this != &str)
{
String tmpStr(str._str);
swap(_str, tmpStr._str);
}
return *this;
}*/
/* 第二种写法 */
String& operator=(String str)
{
swap(_str, str._str);
return *this;
}
~String()
{
if (_str)
{
delete[] _str;
}
}
private:
char *_str;
};
void TestString()
{
String s1("hali");
String s2(s1);
String s3 = s1;
}