如何写出高效C++(继承与面向对象设计)

32.确定你的public继承塑模出is-a关系

public继承主张,能够施行于base class对象身上的每件事情,也可以施行于derived class身上。


33.避免遮掩继承而来的名称

编译器必须实践的名称查找规则:

void Derived::mf4()

{

 ...

 mf2();

...

}

当编译器看到这里使用名称mf2,必须估算它指涉的是什么东西。

首先查找local作用域,若是没有查找到(也就是mf4这个函数的作用域)

那就开始搜索外围作用域,也就是class Derived覆盖的作用域,若是还没有

开始在base class查找,找到了就停止,若是没有找到

找内含Base的namespace(s)的作用域(如果有的话)

最后向global作用域找去

子类内的名称会掩盖base classes内的名称,在public继承下从来没有人希望如此。

为了让被掩盖的名称再见天日,可使用using声明式或转交函数。

using使用方式:

using Base::mf1;//这样Base class内所有名为mf1的函数就都可以用了。

转交函数使用方式:

virtual void mf1()//只需要一个缺省的Base函数的时候可以这样做

{

   Base::mf1();

}


34.区分接口继承和实现继承

表面上直截了当的public继承概念,经过更严密的检查之后,发现它由两部分组成:函数接口继承函数实现继承


纯虚函数的目的是为了让derived classes只继承函数接口。

virtual void draw() const = 0;


声明简朴的(非纯)impure virtual函数的目的,是让derived classes继承该函数的接口和缺省实现。

class Shape

{

 public:

virtual void error(const std::string& msg);

}

相当于告诉子类,你必须支持一个error函数,但是如果你不想写一个也可以使用Shape class提供的缺省版本。


 non-virtual函数具体指定接口继承以及强制性实现继承。

代表的意义是不变性和凌驾特异性,所以他不应该在derived class中被重新定义。


35.考虑virtual函数以外的其他选择

(我觉得。。。virtual挺好的)


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


37.绝不重新定义继承而来的缺省参数值i

virtual函数系动态绑定(你唯一需要去覆写的东西)

缺省参数值是静态绑定


38.通过复合塑模出has-a或"根据某物实现出"

复合就是一个类型中含有其他类型对象,这并不是public继承,他们的意义完全不同。

在应用域复合意味着has-a,在实现域,复合意味着is-implemented-in-terms-of(根据某物实现出)


39.明智而审慎的使用private继承

他的含义也是根据某物实现出,但是复合的优先级要高于private继承


40.明智而审慎的使用多重继承

对于virtual base classes(也相当于对virtual继承)的忠告:

(1)非必要不使用virtual bases,平常请使用non-virtual继承。

(2)如果你必须使用virtual base classes,尽可能避免在其中防止数据。

virtual会增加大小速度,初始化及赋值复杂度等等成本,如果virtual base class不带任何数据,将是最具实用价值的情况。
















你可能感兴趣的:(effective,C++)