第八课 拷贝构造

一、转换构造函数:支持发生隐式类型转换的函数

如果构造函数的参数只有一个且非当前类对象,可以把它当成当前类型使用。

CTest(int a):m_a(a){

}
CTest(int a,int b=30):m_a(a){

}
CTest(int a=20,int b=30):m_a(a){

}
int main()
{
    Ctest tst;
    tst=60;//隐式类型转换
}

以上三种情况支持隐式类型转换

但是可以使用关键字explicit禁止发生隐式类型转换

二、拷贝构造

拷贝构造函数,是编译器默认给提供的一种构造函数,函数原型是CTest(const CTest &tst),重点是一定要加&,不然会产生重复调用的问题(如果值传递,给形参赋值时依旧会调用拷贝构造,产生自己调用自己的情况)

函数体代码不能为空,形参中的对象给this指针指向的对象依次初始化

一旦我们手动重构,编译器就不会再提供了

#include<iostream>
using namespace std;

class CTest{
public:
	int m_a;
	CTest()
	{
		m_a=10;
	}

	CTest(const CTest &tst):m_a(tst.m_a)
	{
		
	}

	~CTest()
	{

	}
};

int main()
{
	CTest tst;
	CTest tst2(tst);

	return 0;
}

二、浅拷贝问题

但是当类中出现指针时,默认的拷贝构造会出现浅拷贝问题

(两个指针指向同一块内存,当一个指针回收内存后,另一个指针再次回收就会崩;通过其中一个指针修改空间内的值,另一个指针读取空间的值,值也会改变)

解决浅拷贝问题使用深拷贝(手动重构拷贝构造函数,并为拷贝的对象开辟属于自己的空间)

    CTest(const CTest &tst):m_a(tst.m_a)
	{
		if(tst.m_p)
		{
			this->m_p=new int(*tst.m_p);
		}else
		{
			this->m_p=nullptr;
		}
	}

函数的参数是结构体或类时,应当尽量避免值传递,尽量使用指针或者引用(避免浅拷贝问题)

四、默认的operator=

空类中也会默认给提供一个operator=,函数体代码不能为空,形参中的对象依次给this对象赋值

一旦手动重构,编译器就不提供默认的了,

CTest& operator=(const CTest& tst)
{
    this->m_a=tst.m_a;
    this->m_p=tst.m_p;
}

但是默认的operator也存在浅拷贝问题,需要深拷贝来解决

	CTest& operator=(const CTest &tst)
	{
		if(this!=tst)
		{
			this->m_a=tst.m_a;
			if(tst.m_p)
			{
				if(this->m_p)
				{
					*this->m_p=*tst->m_p;
				}else
				{
					this->m_p=new int(*tst->m_p)
				}
			}else
			{
				if(this->m_p)
				{
					delete this->m_p;
				}
				this->m_p=nullptr;
			}
		}
	}

五、总结:

类中默认提供的函数

默认无参构造

默认拷贝构造

默认operator=

默认析构函数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值