C++类和对象(HM)

目录

1.拷贝构造函数的调用时机

2.拷贝构造函数的调用规则

3.浅拷贝和深拷贝

(1)浅拷贝

(2)深拷贝

4.初始化列表

5.类作为成员变量


1.拷贝构造函数的调用时机

我们首先要自己定义一个类:

(1)使用已知的对象初始化一个新的对象

这个相当于让已知的对象p1初始化对象p2;

(2)值传递的方式给函数的参数传值

通过打印的结果就可以发现执行了拷贝构造函数,这个是因为我们使用了值传递的方式传递对象p,实际上这两个函数里面的p并不是同一个p,编译器在调用func函数的时候会重新的拷贝一份作为副本;就是说test函数不会直接把自己的p传到func函数里面去,而是重新拷贝一份传给func函数

(3)值的方式返回局部的对象:

这个地方先调用test函数,test函数里面接着调用func函数,func函数会返回一个对象,这个对象就不会直接地返回到我们的test函数里面去 ,而是拷贝一份返回到test函数里面去,我们打印这两个对象的地址就可以发现是不一样的,这个也可以验证拷贝函数是执行了的。

2.拷贝构造函数的调用规则

(1)首先我们必须要知道的是:当我们定义了一个类以后,编译器会自动地实现至少3个函数,一个是默认的构造函数,一个是默认的析构函数,一个是拷贝构造函数(值传递);

(2)当我们自己写了一个自定义的构造函数并且使用的话,如果我们自己不写默认的构造函数,编译其实不会提供的;

(3)当我们写了拷贝构造函数但是不写默认构造函数和自定义构造函数的时候,编译器也不会提供自定义构造和默认构造函数的;

3.浅拷贝和深拷贝

(1)浅拷贝

使用编译器提供的拷贝构造函数,就是浅拷贝:

我们是使用了new在堆区上面开辟空间,把地址传递给了height指针;最后判断是否为空,不是空的话我们就释放掉,然后进行置为空指针;

因为释放是发生在程序销毁的时候,所以我们在析构的那个函数里面释放空间,但是因为定义的对象,先进去的后出来,也就是说先定义的对象后释放,所以p2先执行析构函数,释放空间,这个时候执行了堆区的空间的销毁,p1在执行析构函数,再次释放,就造成了一块空间多次释放,这个就是内存泄漏,导致程序崩溃;

浅拷贝带来的问题就是堆区空间重复释放;

(2)深拷贝

我们在原来的代码的基础上面,添加上我们自己的拷贝构造函数:

person(const person& p)
{
	cout << "拷贝构造函数执行中" << endl;
	age = p.age;
	//height = p.height;//这行代码是编译器默认实现的拷贝函数
	height = new int(*p.height);
}

原来的height = p.height;相当于是把p1的height的地址传递给了p2,这样两个就指向了同样的内存空间,所以会出现交叉多次释放的问题;

我们的解决方案就是重新开辟空间,这样p2的height就会指向新的空间(而不是原来的0x00ff48了);

这样在析构函数执行的时候,p1释放p1的空间,p2释放p2的空间,就不会出现多次释放同一块空间的问题了;----------------------这就是深拷贝。

4.初始化列表

就是提供了一种新的初始化的方法:我们原来是使用这种自定义的构造函数进行初始化:

我们现在使用的是初始化列表:就是在原来的基础上,去掉自定义构造函数的函数体,后面加冒号,写上属性(形参)这种:下面的示例,abc就是我们的属性,a1,b1,c1就是我们的形参:

5.类作为成员变量

打印结果:

这个就是想要说明:A类里面有B成员变量,B也是一个类,这个题就是person类里面有person成员变量,phone也是一个类,执行构造的时候,先执行B的构造,再执行A的构造,执行析沟的时候,先执行A的析构,后执行B的析构,就这个顺序的问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值