1.规则:使用组合往往比使用继承更合理。如果要使用继承的话,定义为public.
第一次看到这个可能有点蒙。
在C++实践中有两种场合:1.实现继承,子类继承父类的实现代码。
2.接口继承,子类仅仅继承父类的方法名称。
继承虽然减少代码量,但是有很多坑。继承是is-a的关系,比如学生继承人,学生 is a 人
比如:1.父类的方法在编译时就确定了,子类不能改变;
2.子类的实现代码散布在父类子类之间,其实更难理解;
3.如果父类修改了方法,比如参数增加,那么子类可能也要修改方法,这是一种高耦合。
组合的思想是什么呢:就是把要组合的类的对象加入到该类中作为自己的成员变量。首先这是低耦合的,而且可以运行时动态绑定对象,用set赋值。
所以,应该优先使用组合,它更稳定和灵活。继承主要优点就是扩展简单,而组合需要精心设计定义。
2、多重继承
真正需要用到多重实现继承的情况少之又少. 只在以下情况我们才允许多重继承: 最多只有一个基类是非抽象类; 其它基类都是以 Interface 为后缀的纯接口类
虽然多重继承更好地复用代码,但是会有很多问题。有时多重实现继承看上去是不错的解决方案, 但这时你通常也可以找到一个更明确, 更清晰的不同解决方案.
3.接口
接口是指满足特定条件的类, 这些类以 Interface 为后缀 (不强制)
定义
当一个类满足以下要求时, 称之为纯接口:
1、 只有纯虚函数 (“=0”) 和静态函数 (除了下文提到的析构函数).
2、没有非静态数据成员
3、没有定义任何构造函数. 如果有, 也不能带有参数, 并且必须为 protected.
4、如果它是一个子类, 也只能从满足上述条件并以 Interface 为后缀的类继承.
接口类不能被直接实例化, 因为它声明了纯虚函数. 为确保接口类的所有实现可被正确销毁, 必须为之声明虚析构函数 (作为上述第 1 条规则的特例, 析构函数不能是纯虚函数)
4、运算符重载
除少数特定环境外, 不要重载运算符. 也不要创建用户定义字面量.
C++ 允许用户通过使用 operator 关键字 对内建运算符进行重载定义 , 只要其中一个参数是用户定义的类型. operator 关键字还允许用户使用 operator"" 定义新的字面运算符, 并且定义类型转换函数, 例 如 operator bool().
运算符重载和自定义字面量都是为了方便用户理解和使用。
缺点很明显:容易出现bug!如果我们不熟悉,会很容易出现错误。
5、存取控制
将 所有数据成员声明为 private, 除非是 static const 类型成员 (遵循常量命名规则). 出于技术上的原因, 在使用 Google Test 时我们允许测试固件类中的数据成员为 protected。
声明次序: public -> protected -> private;