下面是浅拷贝的实例:
class String
{
public:
String(const char* str = "")
{
if (str == nullptr)
{
assert(false);
return ;
}
_str = new char[strlen(str + 1)];
strcpy(_str, str);
} ~String()
{
assert(_str);
delete[] _str;
_str = nullptr;
}private:
char* _str;
};
void Test()
{
String s1("abcd");
String s2(s1);
}
由于s2要调用String类拷贝构造来创建,由于上面没有显式定义则使用系统合成的默认拷贝构造函数。因此二者会调用同一个空间,如下图。
文章图片
在这种情况下,由于String类没有显示定义拷贝构造和赋值运算符重载,此时编译器会自动合成,当s2调用拷贝构造的时候,编译器会调用默认的拷贝构造函数。问题出现了,由于s1,s2公用同一个空间,所以在释放时一个空间被多次释放,从而引起了系统崩溃。
这就是所谓的**浅拷贝。
浅拷贝 也称位拷贝,编译器只是简单的将对象中的值拷贝过来。当多个对象共享一个资源的时候,当一个对象销毁时空间已经被释放,但是另几个对象不知道资源已经释放了,一位还有效,所以当其他对象继续释放的时候,会出现访问违规的现象。
深拷贝 如果一个类中设计资源的管理,即一个对象被多次使用,拷贝构造和赋值运算符必须显示定义。
class String
{
public:
String(const char* str = "")
{
if (str == nullptr)
{
assert(false);
return ;
}
_str = new char[strlen(str + 1)];
strcpy(_str, str);
} String(const String& s)
:_str(new char[strlen(s._str + 1)])
{
strcpy(s._str, _str);
} String& operator=(const String& s)
{
if (this != &s)
{
char* Pstr = new char[strlen(s._str + 1)];
strcpy(Pstr, s._str);
delete[] _str;
_str = Pstr;
}return *this;
} ~String()
{
assert(_str);
delete[] _str;
_str = nullptr;
}private:
char* _str;
};
void Test()
{
String s1("abcd");
String s2(s1);
}
【深拷贝和浅拷贝的理解】深拷贝就是给每个对象独立分配资源,保证对象之间不会因共享资源造成多次释放导致程序崩溃。如下图
文章图片
推荐阅读
- 个人日记|K8s中Pod生命周期和重启策略
- 学习分享|【C语言函数基础】
- C++|C++浇水装置问题
- 数据结构|C++技巧(用class类实现链表)
- C++|从零开始学C++之基本知识
- 步履拾级杂记|VS2019的各种使用问题及解决方法
- leetcode题解|leetcode#106. 从中序与后序遍历序列构造二叉树
- 动态规划|暴力递归经典问题
- 麦克算法|4指针与队列
- 遇见蓝桥遇见你|小唐开始刷蓝桥(一)2020年第十一届C/C++ B组第二场蓝桥杯省赛真题