C++多重继承实现多态

C++ Multiple Inheritance to Implement Polymorphism

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

  1. 这张图想表达什么?

  2. 在这个例子中,Private/Protect 继承的目的是什么?

  3. 如何创建一个实现作为基础class?

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

AV Rule 87

Hierarchies should be based on abstract classes. See Stroustrup 2, 12.5.

Rationale: Hierarchies based on abstract classes tend to focus designs toward producing clean interfaces, keep implementation details out of interfaces, and minimize compilation dependencies while allowing alternative implementations to coexist. See AV Rule 87 in Appendix A for examples.

...

Appendix A - AV Rule 87

Hierarchies based on abstract classes are preferred. Therefore the hierarchies at the top of the diagram are preferred over the hierarchy at the bottom of the diagram.

使用形状的 classic 多态性示例:

5。 我的实施会是以下吗?这对我来说似乎不正确。我担心,我错过了设计的目的。传统上我希望 Right_Triangle 继承自 Triangle。

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

直角三角形是三角形,所以继承是相反的。

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

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

你的例子大部分是正确的,并且符合 AV 87 的精神。虽然你打错了字,实现和 public class 应该是相同的 "kind"(因此,例如,两者都应该是通用三角形):

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

声称直角三角形 三角形的图表是 错误的 ,这是一个常见的误解。直角三角形不是三角形,除非您明确限制可以对三角形执行的操作(例如,将其设置为只读)。三角形可以有任何你想要的边长。从三角形继承的 class 必须仍然*表现得像三角形。它被称为 Liskov Substitution Principle.

既然你不能在任何地方使用RightTriangleclass,那么Triangleclass可以不受限制地使用使 Triangle 作为一个具体的 class 毫无用处(你不能在三角形上设置边长)——因此所示的继承层次结构只是糟糕的设计。

class 层次结构 的设计不一定遵循维恩图,也不应遵循 "everyday truths"。长期的软件工程实践表明,坚持 LSP 可以获得健全的继承图。

是的,证明这种 "right triangle is a triangle" 疯狂 的教科书是错误的 如果它们不提供满足 LSP 的具体设计。对于形状,TrilateralQuadrilateral 接口必须是只读的,特定的顶点或边设置方法只能在派生的 classes 中提供,因为它们坚持不同的限制。派生的具体 classes 需要一个平面层次结构(Square 不是 Rectangle - 如果是,您可以为它设置两个不同的边长!)。同样,就 LSP 而言,Square 不是 Quadrilateral,因为四边形可以具有任意放置的顶点等