【C++基础 02】深拷贝和浅拷贝

我的主题是。每天积累一点点。

===========================================


在类定义中,假设没有提供自己的拷贝构造函数,则C++提供一个默认拷贝构造函数。

C++提供的默认拷贝构造函数的工作方法是:完毕一个成员一个成员的拷贝。假设成员是类对象,则调用其拷贝构造函数或者默认拷贝构造函数。须要注意的是。默认拷贝构造函数不会处理静态成员变量。

简单的自己定义拷贝构造函数:

class Student{
public:
	//拷贝构造函数
	Student(Student& s)
	{
		a = s.a;
	}
protected:
	int a;
};

如上,我们拷贝的策略是一个一个成员的拷贝,可是假设一个类拥有资源,当其构造函数分配了一个资源(如堆内存),而拷贝构造函数没有去分配该资源。那么两个对象都拥有同一个资源,这称为浅拷贝。

浅拷贝的一个问题是,当对象析构的时候,该资源将经历两次资源返还。比方以下这样子:


class Person
{
public:
	Person(char* pN)
	{
		cout<<"Constructing"<<pN<<endl;
		pName = new char[strlen(pN) + 1];
		if(pName != 0)
		{
			strcpy(pName,pN);
		}
	}
	~Person()
	{
		cout<<"Destructing"<<pName<<endl;
		delete pName;
		pName = NULL;
	}
protected:
	char* pName;
};


void main()
{
	Person p1("fzll");
	Person p2 = p1;   //调用默认拷贝函数
}

//输出信息
Constructing fzll
Destructing fzll
Destructing
Null pointer assignment

能够看到,第二次释放资源的时候,出错了。

由于默认拷贝构造函数并没有分配新的资源。

所以我们须要自己定义拷贝构造函数。并分配资源,使拷贝和被拷贝的对象指向不同的资源,这就是深拷贝的概念。C++提供的默认拷贝构造函数就是浅拷贝。


详细例如以下:

class Person
{
public:
	Person(char* pN)
	{
		cout<<"Constructing"<<pN<<endl;
		pName = new char[strlen(pN) + 1];
		if(pName != 0)
		{
			strcpy(pName,pN);
		}
	}
	Person(Person& p)
	{
		cout<<"CopyPerson "<<p.pName<<endl;
		pName = new char[strlen(p.pName) + 1];
		if(pName != 0)
		{
			strcpy(pName,p.pName);
		}

	}
	~Person()
	{
		cout<<"Destructing"<<pName<<endl;
		delete pName;
		pName = NULL;
	}
protected:
	char* pName;
};


void main()
{
	Person p1("fzll");
	Person p2 = p1;   //调用自己定义拷贝函数
}

//输出信息
Constructing fzll
CopyPerson fzll
Destructing fzll
Destructing fzll

堆内存是最经常使用的须要构造拷贝的资源,还有其他资源。比方文件的打开,设备的占有(如打印机)服务业须要深拷贝。


一个非常好的经验是:假设你的类须要析构函数来释放资源。那么它也须要一个拷贝构造函数(深拷贝的方式)。


==============================================================


转载请注明出处:http://blog.csdn.net/shun_fzll/article/details/37774495



原文地址:https://www.cnblogs.com/cynchanpin/p/7169740.html