条款三十二:确定你的public继承塑模出is-a关系
1.所谓最佳设计,取决于系统希望做什么事,包括现在和未来。
2.好的接口可以防止无效的代码通过编译,因此你应该宁可采取“在编译期拒绝企鹅飞行”的设计,而不是“只在运行期才能侦测它们”的设计。
条款三十三:避免遮掩继承而来的名称
1.C++的名称遮掩规则(name-hiding-rule)所做的唯一事情就是:遮掩名称。至于名称是否应相同或不同的类型,函数名称是否重载了不同的类型并不重要。一个名为x的double可以遮掩一个名为x的int;一个mf1()函数可以遮掩一个mf1(x)函数。
2.derived classes内的名称会遮掩base classes内的名称。在public继承下从来没有人希望如此。
3.为了让被遮掩的名称再见天日,可使用using声明式或转交函数。
class Base
{
public:
virtual void mf1()=0;
virtual void mf1(int);
.....
};
class Derived:private Base
{
public:
virtual void mf1()//所谓的转交函数(forwarding function)
{
Base:mf1();
.....
}
}
条款三十四:区分接口继承和实现继承
1.声明一个pure virtual函数的目的是为了让derived classes 只继承函数接口。
2.令人意外的是,我们竟然可以为pure virtual函数提供定义。也就是说你可以为Shape::draw供应一份实现代码,C++并不会发出怨言,但调用它的唯一途径是调用时明确指出其class名称。
Shape *ps=new Rectangle;
ps->draw();//调用Rectangle::draw
ps->Shape::draw()//调用定义为纯虚函数,但却给出实现定义的Shape::draw
3.pure virtual 函数只具体指定接口继承。
4.简朴的(非纯)impure virtual 函数具指定接口继承及缺省实现继承。
5.non-virtual函数具体指定接口继承以及强制性实现继承。
条款三十五:考虑virtual函数意外的其他选择
1.在C++中derived classes可重新定义继承而来的private virtual函数。(public fuction inline private virtual)
条款三十六:绝不重新定义继承而来的non-virtual函数
条款三十七:绝不重新定义继承而来的缺省参数值
1.virtual函数系动态绑定,而缺省参数值却是静态绑定。
2.virtual函数系动态绑定而来,意思是调用一个virtual函数时,究竟调用哪一份函数实现代码,取决于发出调用的那个对象的动态类型。
条款三十八:private继承纯粹是一种实现技术(这就是为什么继承自一个private base class的每样东西在你的class内都是private:因为它们都只是实现枝节而已)