C++浅拷贝和深拷贝的原理

C++浅拷贝和深拷贝的原理

浅拷贝

//头文件.h .hpp
class Student{
	public:
	int age;
	char * name;
	Student(){ cout << "空构造函数" << endl;}
	Student(char * name): Student(name,age){
		cout << "一个参数构造函数this:" <<intthis << endl;}
	Student(char * name, int age){
		cout << "两个参数构造函数this:" <<intthis << endl;
		this->name = (char *)malloc(sizeof (char *) * 10);//指针开辟了10长度的空间
		this->age = age;
		Strcpy(this->name,name);
	}
	Student (const Student & student) {
		
		//自己控制拷贝函数,stduent不是一个指针类型,使用的student.name &不是拿对应指针,
		//而是指C函数中对原对象的引用,传递过来时也不用传递指针
		this->name = student.name;
		this->age = student.age-10;
		cout << "拷贝函数:this->name" <<intthis->name << endl;
	}

	~Student(){
		cout << "析构函数执行this:" <<intthis << endl;
		free(this->name);
		this->name = NULL;
	}
};
int main(){
	Stnedent s1;
	Student s2;
	//第一种情况:两个在栈区开辟了内存,地址都不一样,这点应该没有异议
	//打印两次空参数构造函数,内存地址如:1000H,2000H
	cout << &s1 << endl;
	cout << &s2 << endl;
	
	Stnedent s1;
	Student s2 = s1;
	//第二种情况:两个在栈区开辟了内存,地址不一样:004ff7cc,004ff7bc
	//打印了一次空参数构造函数,调用了一次隐式的拷贝构造函数。
	cout << &s1 << endl;
	cout << &s2 << endl;
	//为什么打印了一次空参数构造函数,出现了两个不一样的地址。
	//我们看下隐式拷贝函数
	Student (const Student & student) {
		cout << "拷贝函数" << endl;
		//自己控制拷贝函数,stduent不是一个指针类型,使用的student.name &不是拿对应指针,
		//而是指C函数中对原对象的引用,传递过来时也不用传递指针
		this->name = student.name;//浅拷贝
		this->age = student.age-10;
}
// 上面的student是s1,它的地址就是目前s1的地址。
//当执行this->name = student.name; this是当前Student结构体,它也是一个对象,区别于s1
//this就是一个新地址,也就是我们的s2。

	return 0;
}
Student getStudent(char * name){
	Student stu(name);
	cout << "getStudnet函数:" << &stu << endl;
	return stu; 
}

void main(){
	Student stu = getStudent("截拳道");
	cont << "main"函数 << &stu << endl;
	//打印顺序:
	//根据:Student(char * name): Student(name,age)
	//先打印两个参数构造函数,再打印一个参数构造函数
	
	//getStudent函数打印,地址类似:1000H
	
	//执行:return stu;  根据我们朴素的认知,每个函数里面的对象,C传递的是指针才不能重新创建
	//C++使用的&引用才不会重新创建,那么这里显示没有
	//那么getStudent函数里面的stu跟mian里面的stu就应该是两个对象
	//结果也是这样的:这里会调用拷贝构造函数出现this构建新地址给main函数的stu
	//执行完拷贝构造函数之后进行getStudent函数退栈回收,执行Student的析构造函数
	//最后再打印 main函数的stu ,下面给贴出输出截图。
	
	//两个函数中的stu是不同的内存地址,指向堆中同一个对象,那么getStudent弹栈回收了一次
	//如果mian函数弹栈,stu析构造函数执行,重复释放空间的问题,该问题涉及深拷贝,后面会解释。
}

深拷贝

//当调用当前方法时:stu这个对象是新的对象,通过拷贝构造函数创建的
void showStudent(Student stu){
	cout << "showStudent函数" << (int)&stu << stu.name << "," << stu.age << endl;
}


void main(){
	Student stu("六分", 22);
	showStudent(stu);
	showStudent(stu);//报错,重复释放,因为student中的name在堆中的对象已经释放了
	//拷贝构造函数中:this->name = student.name; 换成以下代码
	this->name = (char *)malloc(sizeof (char *) * 10);//指针开辟了10长度的空间
	Strcpy(this->name,name);
	//让不同地址指向各自堆中的对象,那么就不会造成重复释放的问题,这就是深拷贝
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值