《Effective C++》笔记 条款31-条款40

条款31,将文件间的编译依存关系降到最低

如果头文件中有任何一个被改变,或者头文件所依赖的头文件有改变,那么每一个依赖它的文件都要重新编译。
类的定义式告诉编译器自己所占的空间大小。
如果使用object reference 或 object pointers 可以完成任务,就不要使用objects。可以只靠一个类型声明式就定义出指向该类型的references和pointers;但如果定义某类型的objects,就需要用到该类型的定义式。
如果可以,尽量以class声明式替换class定义式。注意,当你声明一个函数而它用到某个class时,你并不需要该class的定义;纵使该函数以by value方式传递该类型的参数或返回值。
为声明式和定义式提供不同的头文件。
支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式。基于此构想的两个手段是handle classes和interface classes。
程序库文件应该以“完全且仅有声明式”的形式存在。这种方法不论是否涉及templates都适用。

条款32,确定你的public继承塑膜出is-a关系

public inheritance意味“is a”(是一种)的关系。适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived class对象也都是一个base class对象。

条款33,避免遮掩继承而来的名称

derived classes内的名称会遮掩base classes内的名称。在public继承下从来没有人希望如此。
为了让被遮掩的名称再见天日,可使用using声明式或转交函数。

class Derived: public Base{
public:
	using Base::mf1;
	virtual void mf2()
	{
		Base::mf2();
	}
	void mf1(int x);
	void mf2(int x);
}

条款34,区分接口继承和实现继承

声明一个pure virtual函数的目的就是为了让derived classes只继承函数接口。
可以为pure virtual函数提供定义,C++不会发出怨言,但是调用它的唯一途径是“调用时明确指出其class名称”。

Shape* ps = new Rectangle;
ps->Shape::draw();

声明简朴的(非纯)impure virtual函数的目的,是让derived classes继承该函数的接口和缺省实现。
声明non-virtual函数的目的是为了令derived classes继承函数的接口及一份强制性实现。

条款35,考虑virtual函数以外的其他选择

使用non-virtual interface手法,那是Template Method设计模式的一种特殊形式。它以public non-virtual成员函数包裹较低访问性(private或protected)的virtual函数。
将virtual函数替换为“函数指针成员变量”,这是Strategy设计模式的一种分解表现形式。
以std::function成员变量替换virtual函数,因而允许使用任何可调用物搭配一个兼容于需求的签名式。这也是Strategy设计模式的某种形式。
将继承体系内的virtual函数替换为另一个继承体系内的virtual函数。这是Strategy设计模式的传统实现手法。

条款36,绝不重新定义继承而来的non-virtual函数

non-virtual函数是静态绑定的。由于pB被声明为一个pointer-to-B,通过pB调用的non-virtual函数永远是B所定义的版本,即使pB指向一个类型为“B派生之class”的对象。
virtual函数是动态绑定的,不管是通过pB还是PD调用,都会导致调用派生类的PD所指向的函数。

条款37,绝不要重新定义继承而来的缺省参数值

对象的静态类型,就是它在程序中被声明时所采用的类型。
绝对不要重新定义一个继承而来的缺省参数值,因为缺省参数值都是静态绑定,而virtual函数-你唯一应该覆写的东西-却是动态绑定。

条款38,通过复合塑膜出has-a或“根据某物实现出”

复合的意义和public继承完全不同。
在应用域,复合意味has-a(有一个)。在实现域,复合意味is-implemented-in-terms-of(根据某物实现出)。

条款39,明智而谨慎的使用private继承

private继承意味着is-implemented-in-terms-of(根据某物实现出)。它通常比复合(composition)的级别低。但是当derived class需要访问protected base class的成员,或需要重新定义继承而来的virtual函数时,这么设计是合理的。
和复合(composition)不同,private继承可以造成empty class最优化。这对致力于“对象尺寸最小化”的程序库开发者而言,可能很重要。

条款40,明智而谨慎的使用多重继承

多重继承比单一继承复杂,它可能导致新的歧义性,以及对virtual继承的需要。
virtual继承会增加大小、速度、初始化(及赋值)复杂度等成本。如果virtual base classer不带任何数据,将是最具使用价值的情况。
多重继承的确有正确用途。其中一个情节涉及“public继承某个interface class”和“private继承某个协助实现的class”的两相组合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值