c++ 深复制

浅复制(浅克隆)

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

深复制(深克隆)

被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。

深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。下面举个深拷贝例子:

#include<iostream>
using namespace std;
class Student
{
	private:
		char *name;
	public:
		Student();
		~Student();
		void set(const char* name1)
		{
			if(strlen(name1)+1<256)
			{
				strcpy(name,name1);
			}
		}
	//	Student(const Student &p);
		void print();
};
Student::Student()
{
	name=new char[256];
	cout<<"构造函数被调用"<<endl;
}
Student::~Student()
{
	delete[] name;
	cout<<"析构函数被调用"<<endl;
}
/*
Student::Student(const Student &p)
{
	name=new char[256];		//默认的是 this->name=p.name
	strcpy(name,p.name);
}
*/
void Student::print()
{
	cout<<name<<endl;
}
int main()
{
	Student p1;
	p1.set("Studnet a");
	p1.print();
	Student p2(p1);
	p2.set("Student b");
	p2.print();
	p1.print();
	return 0;
}
在上面代码中,如果不重新定义复制构造函数则会发生内存报错,其原因在于默认的复制构造函数中是这样的this->name=p.name,这样p1的指针就指向了p2,当然原来的p1所指向的内容就丢失了,在析构的时候对指向同一块内存的指针释放了两次,当然就会报错啦。
例二:
#include<iostream>
using namespace std;
class Student
{
	private:
		char *name;
	public:
		Student(const char *pName="NO Name")
		{
			name=new char[strlen(pName)+1];			
			strcpy(name,pName);
		}
		void UpperName()
		{
			strupr(name);
		}
		void show()const
		{
			cout<<name<<endl;
		}
		~Student()
		{
			if(name != NULL)
			{
				delete[] name;
			}
		}
	/*	Student(Student &p)
		{
			name=new char[strlen(p.name)+1];
			strcpy(name,p.name);
		}
	*/	
		
};
int main()
{
	char str[10]="Student a",*ptr=new char[10];
	strcpy(ptr,"Student b");
	Student p1(str),p2(ptr),p3("Student c");
	p1.show();
	p2.show();
	p3.show();
	cout<<"-------------"<<endl;
	strcpy(str,"Studnt c");		//这个修改不影响对象p1
	p1.show();
	delete[] ptr;				//这个释放不影响p2
	p2.show();
	p3.UpperName();			//对象属性的修改由对象自己作主
	p3.show();
	Student p4=p1;
	p4.show();
	p4.UpperName();
	p4.show();
	p1.show();			//出问题,pn1内容改变,并且内存报错,重载复制构造函数  Student(Student &p)
	return 0;
}




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值