【C++学习】关于拷贝构造函数个人理解

一、什么是拷贝构造函数?

构造函数按类型可以分为 普通构造函数 与 拷贝构造函数
拷贝构造函数格式:类名(const 类名& 形参名)
默认拷贝构造函数作用:对属性进行值拷贝(遇到指针会出现深拷贝与浅拷贝的问题),代码类似于

Person(const Person& p) {
	this->m_a = p.m_a;
	this->m_b = p.m_b;//会出现浅拷贝带来堆区内存重复释放问题
}
int m_a;
int *m_b;

编译器会给类自动添加至少3个函数(还有个赋值运算符operator=)
①无参构造函数
②析构函数
③拷贝构造函数
注意:当自定义拷贝构造函数的时候,系统不会自动添加其他函数(应该包括析构函数)
当自己定义有参时,系统不会添加无参,但是会有拷贝构造函数

二、什么时候调用拷贝构造函数

拷贝构造函数在三种情况下调用
1、用已经创建好的对象为新对象初始化

	Person p1(10);
	//以下两种都会调用拷贝构造函数
	Person p2(p1);
	Person p3 = p1;//不是赋值,是初始化

在这里插入图片描述

那么对象何时销毁呢?
对象何时销毁也与其作用域有关。
变量(对象是类类型的变量)的作用域决定了变量的有效范围,变量的有效作用域从它的定义点开始,到这个变量上面最邻近的开括号与之配对的闭括号。
2、以值的方式传递给函数

void doWork(Person p) {

}
void test02() {
	Person p1(10);
	doWork(p1);
}

在这里插入图片描述3、函数以值的方式返回

Person doWork2() {
	Person p(10);
	return p;
}
void test03() {
	doWork2();
}

在这里插入图片描述

三、深拷贝与浅拷贝

浅拷贝:对值进行赋值,编译器写的是浅拷贝
深拷贝:创建一个新的堆区,进行拷贝
例如:
当使用系统所给的拷贝构造函数时(浅拷贝)
在这里插入图片描述当时由于堆区开辟的内存,需要自己手动释放,所以添加析构函数

class Person
{
public:
	int* m_A;
	Person(int a) {
		m_A = new int(a);//注意new开辟的堆区内存返回的是指针
	}
	~Person() {
		if (m_A!=NULL)
		{
			delete m_A;
			m_A = NULL;
		}
	}
};

此时运行系统错误,为什么呢?
因为浅拷贝将 p1的m _a的值,也就是地址,直接赋给了p2的m_a,当由于栈区是先进后出,所以p2先调用析构函数,释放了堆区,由于p1与p2的m_a指向的地址相同,所以p1再释放的时候出现重复释放堆区内存。
在这里插入图片描述所以需要通过深拷贝,新开辟一个堆区,进行拷贝

Person(const Person& p) {
	this->m_A = new int(*p.m_A);
}

浅拷贝与深拷贝问题主要是出现在类属性有在堆区开辟的情况下。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值