C++ Primer 第十五章 面向对象程序设计 15.7 构造函数和拷贝控制 练习和总结

本文详细探讨了C++中的构造函数和拷贝控制,包括虚析构函数的重要性,如何在继承体系中正确处理拷贝构造和拷贝赋值,以及派生类如何实现拷贝控制。强调了虚析构函数在多态场景下回收资源的关键作用,并通过实例解析了构造和析构过程中虚函数调用的规则。此外,还介绍了C++11中继承构造函数的概念和使用场景。
摘要由CSDN通过智能技术生成

15.7 构造函数和拷贝控制

15.7.1 虚析构函数

在继承体系中,基类的指针,引用可以绑定派生类的对象,使用指针时,我们使用delete来回收这个指针所管理的对象。但是在继承体系中,这个指针可能指向的是其子类的对象,为了正确的调用子类的析构函数,应该将基类的析构函数声明为虚析构函数

只要基类的析构函数为虚析构函数,那么其子类的析构函数(编译器合成的或者自己定义的)也默认是析构函数。

注意,一旦我们显式的写出了析构函数,那么编译器将不会为我们合成移动操作。

练习
15.24

在继承体系中的类需要虚析构函数,和普通析构函数一样虚析构函数也需要回收自己类中指针所管理的资源。

15.7.2 合成拷贝控制与继承

派生类合成的拷贝构造、拷贝赋值、析构函数在执行时会调用其父类对应的操作。

对于拷贝构造和默认构造都是先调用基类的构造函数(在派生类的初始化列表中),再调用派生类的构造函数。

而析构函数则是先调用派生类的析构,再调用基类的析构。

如果基类中某一个拷贝控制操作(拷贝构造,默默认构造,拷贝赋值,移动构造,移动赋值,析构)被定义为删除或者不可访问,则派生类对应的操作也被定义为删除。
特别的,如果基类的析构函数被定义为删除,则派生类的合成的默认构造函数和拷贝构造函数将被定义为删除。(这一点感觉只能硬记)

练习
15.25

如果不定义Disc_quote的默认构造函数,因为其定义了其他的构造函数,所以默认构造函数就变成了以删除的函数,那么Bulk_quote的默认构造函数因为无法调用其父类的构造函数也将变为删除的函数。

15.7.3 派生类的拷贝控制成员

派生类默认的拷贝控制成员会调用基类拷贝控制成员的对应版本。

构造函数

如果我们显式的定义了拷贝构造函数,则也需要显式调用基类的拷贝构造函数,否则其将调用基类的默认构造函数来初始化基类的成员。

class A
{
   
public:
	A(const A& a) {
   };
	virtual void func() {
   
		cout<<"A::func"<<endl;
	}
	A(A&& a) {
   

	}
private:

};

class B:public A
{
   
public:
	B(const B& b):A(b) {
   
	};
	B(B&& b):A(std::move(b)) {
   

	}
private:

};

在B的拷贝构造函数中,调用A的拷贝构造函数,这可以传入b的对象。

B(const B& b):A(b) {
   
};

在B的移动构造函数中,调用A的移动构造函数,这里就有问题了,为什么移动构造函数中需要b本来就是右值,还要调用move来传入A的移动构造函数呢。

这里其实是一个误区,因为b绑定的对象是右值,但是b对象本身其实是一个左值。所以还需要将b传入move这也才能正确的调用A的移动构造函数。

B(B&& b):A(std::move(b)) {
   

}
赋值运算符

不同于拷贝构造,赋值运算符只能在函数体中调用父类的辅助运算符。调用方式就是operator=()

B& operator=(const B&b) {
   
		A::operator=(b
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值