C++拷贝构造函数调用时机及陷阱

####拷贝构造调用有四种

  1. 用一个对象 **初始化 ** 另一个对象时
  2. 函数实参传递给形参时,这也差不多是初始化啦
  3. 函数返回值,C++编译器在这做的就很奇怪了,今天早上调了一早上
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>

using namespace std;

//大家可以看一下陷阱在哪
class Teacher
{
public:
	Teacher(char *name, int age)
	{
		this->name_len = strlen(name);
		this->name = new char[name_len + 1];
		strcpy(this->name, name);
		this->age = age;
	}
	Teacher(const Teacher &obj)
	{
		cout << "调用了copy构造函数... " << endl;
		if (obj.name_len < 0)
		{
			return;
		}
		if (name != NULL) //
		{
			delete[] name;
			name = NULL;
		}
		name_len = obj.name_len;
		name = new char[name_len + 1];
		strcpy(name, obj.name);
		age = obj.age;
	}
public:
	char* name; //姓名
	int name_len; //姓名的长度
	int age; //年龄
};
  • 看着好像是问题不大,我们来运行一下
void main()
{
	Teacher t1("calf", 50);
	cout << t1.age << t1.name << endl;

	Teacher t2("aaaa", 15);
	cout << t2.age << t2.name << endl;

	Teacher t3 = t1;
	cout << t3.age << t3.name << endl;
}

这里写图片描述
ok,运行成功

  • 然后我们开始测试函数返回值调用的copy构造函数
//先写个函数
Teacher getT()
{
	Teacher tmp("young", 12);
	return tmp;
}
//调用试试
void main()
{
	Teacher t1("calf", 50);
	cout << t1.age << t1.name << endl;

	Teacher t2("aaaa", 15);
	cout << t2.age << t2.name << endl;

	Teacher t3 = t1; //加了这四行
	cout << t3.age << t3.name << endl;	
	t3 = getT(); 
	cout << t3.age << t3.name << endl;
}

这里写图片描述
执行到这就宕机了,,,
这里写图片描述
通过调试,发现拷贝构造函数里去掉这几行就行了

Teacher(const Teacher &obj)
	{
		cout << "调用了copy构造函数... " << endl;
		if (obj.name_len < 0)
		{
			return;
		}
		/*这几行
		if (name != NULL) //
		{
			delete[] name;
			name = NULL;
		}
		*/
		name_len = obj.name_len;
		name = new char[name_len + 1];
		strcpy(name, obj.name);
		age = obj.age;
	}

查了些资料,原因如下:
在执行这句的时候 t3 = getT(); , 会产生一个匿名对象(就是没有任何调用的对象),会先把getT()函数的tmp对象通过copy构造函数,初始化这个匿名对象,然后析构这个tmp对象完成退出这个函数,然后通过等号操作符(可以重载)把产生的匿名对象赋给t3,再析构这个匿名对象。
这里写图片描述

  • 现在开始说我们的陷阱了,个人觉得宕机的原因: C++除了全局变量以外的变量都不会自动赋初值,即我们Teacher类的char *name的初始值是随机的,匿名对象的name值不为空,故析构了还没分配内存的name野指针。

ps:C++博大精深,觉得这个解析可能也不是很合理,望指点。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值