13.拷贝构造函数

13.拷贝构造函数

1.拷贝构造函数
  • 1.拷贝构造函数的作用:本质上拷贝构造函也是一种构造函数
  • 2.拷贝构造函数的调用时机:与普通的构造函数不同的是,当用一个对象创建另一个对象时才调用拷贝构造函数
  • 3.缺省拷贝构造函数的作用:如果我们自己没有书写拷贝构造函数,默认情况下系统会创建默认拷贝构造函数,默认的拷贝构造函数就是完全将对象1拷贝给对象2,以memcpy的形式
  • 4.如何自己创建拷贝构造函数
//前面已有CStudent的构造函数
class CStudent
{
public:
	CStudent(){}//构造函数
	//拷贝构造函数
	CStudent(CStudent& obj)
	{
		printf("拷贝构造函数");
	}
	//CStudent(CStudent& obj) = delete;//禁用默认的拷贝构造函数
	//CStudent(CStudnet& obj) = default;//使用默认的拷贝构造函数
};
int main()
{
	CStudent stu1;
	CStudent stu2 = stu1;//使用stu1这个对象创建stu2时,调用默认拷贝构造函数
}
2.拷贝构造函数与深拷贝和浅拷贝

先看一个例子:

class CStudent
{
public:
	//构造函数
	CStudent()
	{
		//在构造函数中为m_szName开辟了堆空间(分配动态内存)
		//因为我们这里开辟了堆空间,因此函数成员中有了需要释放的资源
		m_szName = (char*)malloc(255);
	}
	//析构函数
	~CStudent(){}
	/*自定义的拷贝构造函数
	CStudent(CStudent& obj)
	{
	}
	*/
private:
	int m_nStuID;
	char* m_szName;
};
int main()
{
	CStudent stu1;
	//使用一个对象构建另一个对象时,如果没有自定义的拷贝构造函数,系统会调用默认的拷贝构造函数
	CStudent stu2(stu1);
	reutrn 0;
}

大家有没有发现程序中存在问题

  • 在CStudent stu1;时我们调用了构造函数,开辟了堆空间
  • 在CStudent stu2(stu1);时,由于我们没有自定义拷贝构造函数,系统调用了默认的拷贝构造函数,默认拷贝构造函数是浅拷贝,即仅仅是将stu2指向了与stu1相同的内存空间,并没有开辟新的内存空间,然后再将stu1的内容copy到stu2中
  • 当main函数执行结束,将要退出局部作用域时,此时会调用析构函数,首先进行stu1的析构,释放了之前开辟的堆空间,然后进行stu2的析构,但是这时就会遇到问题,因为我们之前使用的是默认的拷贝构造函数,默认拷贝构造函数并没有开辟新的堆空间用来存放stu2,而是将stu2指向了与stu1相同的内存空间,此时就会造成空间的重复释放,因此会造成错误
  • 出现错误的原因是:默认构造函数是浅拷贝,并未开辟新的内存空间,在函数退出时调用析构函数造成了资源空间的重复释放
何时我们应该自己定义拷贝构造函数,何时我们应该采用系统默认的拷贝构造函数呢?

答:当对象中的成员函数存在一种需要分配的资源时,为了避免调用默认拷贝构造函数时的浅拷贝问题,造成析构时对资源空间的重复释放,我们需要重写拷贝构造函数或禁用

如何重写拷贝构造函数?
class CStudent
{
public:
	//构造函数
	CStudent()
	{
		//在构造函数中为m_szName开辟了堆空间(分配动态内存)
		//因为我们这里开辟了堆空间,因此函数成员中有了需要释放的资源
		m_szName = (char*)malloc(255);
	}
	//析构函数
	~CStudent(){}
	//自定义的拷贝构造函数
	CStudent(CStudent& obj)
	{
		//这种是深拷贝的做法:创建堆空间
		m_szName = (char*)malloc(255);
		if(m_szName == nullptr)
		{
			return;
		}
		//然后将内容拷贝到新开辟的堆空间
		memcpy(this->m_szNmae,obj.m_szName,255);
		//浅拷贝如何做的:
		//this->m_szName = obj.m_szName;
	}
	
private:
	int m_nStuID;
	char* m_szName;
};
int main()
{
	CStudent stu1;
	//使用一个对象构建另一个对象时,如果没有自定义的拷贝构造函数,系统会调用默认的拷贝构造函数
	CStudent stu2(stu1);
	reutrn 0;
}

memcpy()函数介绍
深拷贝与浅拷贝的区别

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值