"public 继承"意味 is-a。适用于 base classes 身上的每一件事情一定也适用于derived classes 身上,因为每一个 derived class 对象也都是一个 base class 对象。
个人理解:基类的函数适用于派生类的每一个函数。
derived classes 内的名称会遮掩 base classes 内的名称。在 public 继承下从来没有人希望如此。
为了让被遮掩的名称再见天日,可使用 using 声明式或转交函数( forwarding functions)。
个人理解:相同名称会有覆盖的问题,public 继承可以用using 声明, private函数可以使用转交函数。
接口继承和实现继承不同。在 public 继承之下, derived classes 总是继承 base class的接口。
pure virtual 函数只具体指定接口继承。
简朴的(非纯) impure virtual 函数具体指定接口继承及缺省实现继承。
non-virtual 函数具体指定接口继承以及强制性实现继承。
个人理解:接口继承只继承函数接口,实现继承继承接口和实现、并且又能够重写;
virtual 函数的替代方案包括 NVl 手法及 Strategy 设计模式的多种形式。 NVI 于法自身是一个特殊形式的 Template Method 设计模式.
将机能从成员函数移到 class 外部函数,带来的一个缺点是,非成员函数无法访问 class 的 non-public 成员。
std::function 对象的行为就像→般函数指针。这样的对象可接纳"与给定之目标签名式 (target signature) 兼容"的所有可调用物 (callable entities)。
个人理解:
- 使用NVI手法,他是用public non-virtual成员函数包裹较低访问性(private和protected)
- 的virtual函数;
-
- 将virtual函数替换成“函数指针成员变量”,这是strategy设计模式的一种表现形式;
-
- ****以tr1::function成员变量替换virtual函数,因而允许使用任何可调用物(callable entity)
- 搭配一个兼容与需求的签名式,这也是strategy设计模式的某种形式;
-
- 将继承体系内的virtual函数替换成另一个继承体系内的virtual函数。这是strategy设计模式的传统做法;
绝对不要重新定义继承而来的 non-virtual 函数
个人理解:继承类会覆盖基类中函数实现;
绝对不要重新定义一个继承而来的缺省参数值,因为缺省参数值都是静态绑定,而virtual函数一一你唯一应该覆写的东西一一却是动态绑定。
个人理解:
- class Shape{
- public:
- enum ShapeColor {Red, Green, Blue};
- virtual void draw(ShapeColor color=Red) const = 0;
- };
-
- class Rectangle : public Shape{
- public:
- virtual void draw(ShapeColor color=Green) const;//和父类的默认参数不同
- }
-
- Shape* pr = new Rectangle; // 注意此时pr的静态类型是Shape,但是他的动态类型是Rectangle
- pr->draw(); //virtual函数是动态绑定,而缺省参数值是静态绑定,**所以会调用Red,而不是green**
-
- class Rectangle : public Shape{
- public:
- virtual void draw(ShapeColor color= Red) const; //**(代码重复且带有相依性,不可取)**
- }
-
- **//可以更换为NVI的手法可以实现目的**
- class Shape{
- public:
- enum ShapeColor {Red, Green, Blue};
- void draw(ShapeColor color=Red) const {
- doDraw();
- }
- private:
- virtual void doDraw(ShapeColor color) const = 0;
- };
-
- class Rectangle : public Shape{
- public:
- virtual void doDraw(ShapeColor color) const;
- }
复合( composition) 的意义和 public 继承完全不同。
在应用域 (application domain) ,复含意味 has -a (有一个)。在实现域(implementation domain) ,复合意味 is-implemented-in-terms-of(根据某物实现出)。
个人理解:
- //应用领域:
- class Address {...};
- class PhoneNumber {...};
- class Person {
- ...
- private:
- std::string name;
- Address address;
- PhoneNumber phone;
- }
-
- //实现域:set并不是一个list,但是set可以has a list:
- template<class T>
- class Set{
- public:
- void insert();
- //.......
- private:
- std::list
rep; - }
Private 继承意味 is-implemented-in-terms of (根据某物实现出)。它通常比复合(composition) 的级别低。但是当 derived class 需要访问 protected base class 的成员,或需要重新定义继承而来的virtual 函数时,这么设计是合理的。
和复合( composition) 不同, private 继承可以造成 empty base 最优化。这对致力于"对象尺寸最小化"的程序库开发者而言,可能很重要。
个人理解:如果D以private形式继承B,private继承意味着只有实现部分被继承,而没有其他含义。尽可能的使用复合,必要时才使用private(总结中提到的两种情况)
多重继承比单一继承复杂。它可能导致新的歧义性,以及对 virtual 继承的需要。
virtual 继承会增加大小、速度、初始化(及赋值)复杂度等等成本。如果 virtual base classes 不带任何数据,将是最具实用价值的情况。
多重继承的确有正当用途。其中一个情节涉及"public 继承某个 Interface class" 和 "private 继承某个协助实现的class" 的两相组合。
个人理解:多重继承基类对象存在多个