C ++多重继承实现多态性

时间:2015-03-17 15:42:22

标签: c++ inheritance multiple-inheritance

JSF C++ Coding Standards 中,AV规则87显示了抽象基类图和作为多重继承的实现。

  1. 这张图试图显示什么?

  2. 在此示例中,私有/保护继承的目的是什么?

  3. 如何将实现创建为基类?

  4. AV规则87中的图表显示D1继承自impl;这是一个与接口无关的不同实现吗?

  5.   

    AV规则87

         

    层次结构应该基于抽象类。见Stroustrup 2,   12.5。

         

    理由:        基于抽象类的层次结构倾向于将设计集中在生成干净的接口上,从而保持实现细节   接口,并在允许时最小化编译依赖性   共存的替代实现。请参阅附录A中的AV规则87   例如。

         

    ...

         

    附录A - AV规则87

         

    首选基于抽象类的层次结构。因此   图表顶部的层次结构优先于层次结构   在图的底部。   JSF AV Rule 87

    使用形状的经典多态性示例:

    Classic Shapes Polymorphism example

    5。 我的实施是否会如下?这对我来说似乎不对。我担心,我错过了设计的目的。传统上我希望Right_Triangle继承三角形。

     class Shape{};                              // Interface
     class Right_Triangle{};                     // Impl    
     class Triangle : public Shape,
                      private Right_Triangle {}; // D1
    

2 个答案:

答案 0 :(得分:2)

右三角是一个三角形,所以继承是另一种方式。

在您的示例中,Shape必须是根据编码规则的抽象类。因此shape只能声明纯虚函数,如Print(),Load(),rotate(),...

要继承自另一个实现(在形状层次结构旁边),不应使用公共继承。

答案 1 :(得分:2)

你的例子大多是正确的,并且坚持AV 87的精神。你已经犯了一个错字,实现和公共类应该是相同的“种类”(因此,两者都应该是一个通用的三角形,例如):

class IShape { ... };      
class TriangleImpl { ... }; 
class Triangle : public IShape,
                 private TriangleImpl { ... };

声称右三角形三角形的图表错误,以及一个常见的误解。直角三角形不是三角形,除非您明确限制使用三角形可以做的事情(例如,将其设为只读)。三角形可以具有您想要的任何边长。从三角形继承的类仍然必须像三角形一样。它被称为Liskov Substitution Principle

由于无法在任何地方使用RightTriangle类,因此可以使用Triangle类,而不会使Triangle作为具体类无用(您不能在三角形上设置边长) - 因此所显示的继承层次结构只是糟糕的设计。

类层次结构的设计不一定遵循维恩图,也不应遵循“日常事实”。长期的软件工程实践表明,当您坚持使用LSP时,可以获得合理的继承图。

是的,如果教科书没有提供满足LSP的具体设计,那么证明这种“直角三角形是三角形”的教科书是错误的。在形状的情况下,TrilateralQuadrilateral接口必须是只读的,并且特定的顶点或边缘设置方法只能在派生类中提供,因为它们遵循不同的限制。派生的具体类需要一个平面层次结构(Square不是Rectangle - 如果是,你可以为它设置两个不同的边长!)。同样,就LSP而言,Square不是Quadrilateral,因为四边形可以有任意放置的顶点等。