C++细节 深拷贝和浅拷贝(位拷贝)详解「建议收藏」

C++细节 深拷贝和浅拷贝(位拷贝)详解「建议收藏」前提 在对象拷贝过程中,如果没有自定义拷贝构造函数,系统会提供一个缺省的拷贝构造函数,缺省的拷贝构造函数对于基本类型的成员变量,按字节复制,对于类类型成员变量,调用其相应类型的拷贝构造函数。阅读《高质量的cc++编程》,第9章有这样一段话,类似的话在《c++primer》《effectiveC++》都有所提及,那就是拷贝构造函数问题,这个是类编写者的一个基础问题。位拷贝(浅…

大家好,欢迎来到IT知识分享网。

前提 

在对象拷贝过程中,如果没有自定义拷贝构造函数,系统会提供一个缺省的拷贝构造函数,缺省的拷贝构造函数对于基本类型的成员变量,按字节复制,对于类类型成员变量,调用其相应类型的拷贝构造函数。

阅读《高质量的c c++编程》,第9章有这样一段话,类似的话在《c++primer》《effective C++》都有所提及,那就是拷贝构造函数问题,这个是类编写者的一个基础问题。

C++细节 深拷贝和浅拷贝(位拷贝)详解「建议收藏」

C++细节 深拷贝和浅拷贝(位拷贝)详解「建议收藏」

位拷贝(浅拷贝)举例,a指向b,b的改变其实会影响a的改变,同时a原本指向的空间发生泄漏。

然后这种情况下有了深拷贝。

我对其绘制思维导图,方便阅读并用分点的方式进行总结;

 

何时调用?

以下情况都会调用拷贝构造函数:
一个对象以值传递的方式传入函数体
一个对象以值传递的方式从函数返回
一个对象需要通过另外一个对象进行初始化。

 

浅拷贝:位拷贝,拷贝构造函数,赋值重载

多个对象共用同一块资源,同一块资源释放多次,崩溃或者内存泄漏

 

深拷贝:每个对象共同拥有自己的资源,必须显式提供拷贝构造函数和赋值运算符。

缺省拷贝构造函数在拷贝过程中是按字节复制的,对于指针型成员变量只复制指针本身,而不复制指针所指向的目标–浅拷贝。

我们用自己编写的string举例


class String
{

public:
	const char* c_str()
	{
		return _str;
	}

	String(const char* str = "")
		:_str(new char[strlen(str) + 1])
	{
		strcpy(_str, str);
	}
	String(const String &s)
		:_str(NULL)
	{
		String tmp(s._str);
		swap(_str, tmp._str);
	}
	~String()
	{
		if (_str)
		{
			delete[]_str;
		}
	}

private:
	char* _str;

};

通过开辟空间的方式,进行深拷贝

	String s1("字符串1");
	String s2(s1);
	cout << s2.c_str() << endl;

C++细节 深拷贝和浅拷贝(位拷贝)详解「建议收藏」

拷贝成功;

这种方式采取的  拷贝构造,注意这个

	String(const String &s)
		:_str(NULL)
	{
		String tmp(s._str);
		swap(_str, tmp._str);
	}

代码解析:其中this指向拷贝的对象,s指向试图拷贝的原对象。(测试中的  this指向s2,s指向s1)

其中利用构造函数开辟空间,建立临时的tmp,然后进行交换完成拷贝。

当然,我们也可以使用赋值操作符重载完成这一功能(如例子s1=s2)

	String& operator =(const String& s)
	{
		if (this != &s)
		{
			String tmp(s._str);
			swap(tmp._str, _str);
			return *this;
		}
	}//调用构造析构
//本代码是tmp调用的构造函数
	String(const char* str = "")
		:_str(new char[strlen(str) + 1])
	{
		strcpy(_str, str);
	}
/*String tmp(s._str)
调用这个构造函数,开辟空间,建立一个和s1一样大小的空间,并拷贝值
*/

 

代码解析:

C++细节 深拷贝和浅拷贝(位拷贝)详解「建议收藏」

s1(this),s2(s)

建立tmp,tmp有和s2一样大的空间,一样的数值(调用构造函数),然后交换使s1(this)指向2号空间,获得拷贝,tmp指向3号空间,tmp生命周期结束调用析构函数释放,功能完成。

C++细节 深拷贝和浅拷贝(位拷贝)详解「建议收藏」

 

 

当然 赋值重载函数可以写的更加简洁

	String &operator=(String s)
	{
		swap(_str, s._str);
		return *this;
	}

利用tmp的方式是 借助构造函数,这一种方式则是借助拷贝构造函数

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/25944.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信