深拷贝和浅拷贝的理解

下面是浅拷贝的实例:

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类拷贝构造来创建,由于上面没有显式定义则使用系统合成的默认拷贝构造函数。因此二者会调用同一个空间,如下图。
深拷贝和浅拷贝的理解_第1张图片
在这种情况下,由于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);
}

深拷贝就是给每个对象独立分配资源,保证对象之间不会因共享资源造成多次释放导致程序崩溃。如下图
深拷贝和浅拷贝的理解_第2张图片

你可能感兴趣的:(C++)