浅拷贝:
定义:浅拷贝(Shallow Copy)是一种简单的对象复制方式,将一个对象的数据成员直接复制给另一个对象(通常是通过默认的复制构造函数或赋值运算符实现),这些数据成员可以是基本类型或指向其他对象或资源的指针。具体地说,浅拷贝只是复制指针的值,而不是复制所指向的内存区域。
因此,如果被浅拷贝的对象存在一个或多个指针成员,则会导致多个对象共享同一块内存区域。当其中任何一个对象析构时,该指针将被 delete
解除绑定的内存区域,从而导致其他引用的该内存区域变得无效,从而产生不可预期的行为(如悬挂指针、内存泄漏等)。
=》缺点总结:
1.多次析构(浅拷贝n次就析构n+1次)
解决方法:增加一个引用计数,每个对象析构时,--引用计数,最后一个析构的对象释放空间
2.一个对象修改影响另一个对象
解决方法:写时拷贝(本质,延迟拷贝:谁去写,谁做深拷贝)
没人写不就赚了么
浅拷贝示例:
#pragma once
#include <iostream>
#include <assert.h>
using namespace std;
class mystring
{
public:
//全缺省构造函数
mystring(const char* str = "")//""是常量字符串,常量字符串默认自带\0
//受声明顺序的影响
/* :_size(strlen(str))
,_capacity(_size)
,_str(new char[_capacity+1])*/
{
//不受声明顺序的影响
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];
strcpy(_str, str);
}
//析构函数
~mystring()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
private:
size_t _size;
size_t _capacity;
char* _str;
};
//拷贝构造
int main()
{
mystring s1("hello world");
mystring s2(s1);
return 0;
}
文字说明:
s2析构结束后,s1析构s2刚销毁的空间。故会发生警告
深拷贝:
定义:深拷贝(Deep Copy)是一种对象复制方式,将一个对象或资源以及其指向的某些对象或资源一起复制给另一个对象。具体地说,深拷贝会为新对象重新分配内存空间,并将被复制对象的数据成员递归地复制到新对象中。
因此,如果被深拷贝的对象存在指针等非基本类型的成员变量,那么深拷贝会额外申请一块与原对象所使用的内存区域大小相同的内存,将其中的数据递归地复制到新对象中,并返回指向该内存区域的指针。
示例:
#pragma once
#include <iostream>
#include <assert.h>
using namespace std;
class mystring
{
public:
// 全缺省构造函数
mystring(const char* str = "")
: _size(strlen(str)), _capacity(_size), _str(new char[_capacity + 1])
{
strcpy(_str, str);
}
// 拷贝构造函数
mystring(const mystring& str)
: _size(str._size), _capacity(str._capacity), _str(new char[_capacity + 1])
{
strcpy(_str, str._str);
}
// 析构函数
~mystring()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
private:
size_t _size;
size_t _capacity;
char* _str;
};
int main()
{
mystring s1("hello world");
mystring s2(s1);
return 0;
}
图解:
文字说明:
在拷贝构造函数中,我们使用深拷贝方式将 _str
字符指针所指向的内存区域递归地复制到新对象中,并确保在新对象销毁时释放所申请的内存空间。这样,当新对象与原对象均被销毁时,它们所使用的内存空间是相互独立的,避免了内存泄漏和悬挂指针等问题