如何在 UML 图中表示 C++ 私有继承?

How to represent C++ private inheritance in an UML diagram?

在 C++ 中,可以通过 publicprotectedprivate 继承创建子 class。在 UML class 图中用什么符号表示?我正在考虑在箭头上贴上标签,但不确定这是否是常见做法。

什么是 C++ 中的私有继承?

C++中的

Private inheritance,如:

class B1 {
public: 
   void test(); 
   ...
};
class D1 : private B1 {
public:
   void demo() { test(); }
...
}; 

意味着 D1 的每个实例都是 B1 的实例,但这对外界是隐藏的。这个奇怪的构造旨在通过重用基 class 的代码来实现派生 class,但好像没有继承。

因此,与 public 继承不同,D1 对象不能用于需要 B1 对象的地方:

 B1 *p = new D1;     //ouch -> error: ‘B1’ is an inaccessible base of ‘D1’

这是UML继承吗?

在 UML 中,当一个派生的 class 专门化一个更一般的基础 classe 时,它​​意味着以下内容:

Type conformance means that if one Type conforms to another, then any instance of the first Type may be used as the value of a TypedElement whose type is declared to be the second Type. A Classifier is a Type, and conforms to itself and to all of its generalizations.

因此在 UML 中,如果 D1 特化(即继承自)B1,则始终可以使用 D1 实例代替 B1 对象。这与 C++ 私有继承不匹配。

此外,接口与其实现之间也没有实现关系,因为D1不符合B1定义的接口:

An InterfaceRealization relationship between a BehavioredClassifier and an Interface implies that the BehavioredClassifier conforms to the contract specified by the Interface by supporting the set of Features owned by the Interface, and any of its parent Interfaces.

如何用标准 UML 表示它?

很明显,存在依赖关系:D1依赖于B1。所以你可以简单地显示依赖关系。但这并不能真正帮助把握那种关系,也不是很有用。 (除非你加评论解释)

因此,更好的方法是映射 UML 以匹配 C++ 语义。在这方面,您可以设想将私有继承建模为组合关系:

Why? 因为情况与以下组合替代方案非常相似(尽管不完全):

class B2 {
public: 
   void test(); 
   ...
};

class D2 {
private: 
   B2 base;  // instead of private inheritance
public:
   void demo() { base.test(); }  // base members accessed via base
...
}; 

所以我们在这里的 UML 模型中所做的就是明确表示在任何 D1 实例中,都有一个 B1 子对象不能直接从外部世界访问。

编辑:其他选择?

以前和现在 obsolete UML 1.4,泛化关系可以有一个原型 «Implementation» 可以满足您的需求,但自 2005 年以来不再受支持,并且可能会误导一些联想的读者接口的“实现”:

Specifies that the child inherits the implementation of the parent (its attributes, operations and methods) but does not make public the supplier's interface, nor guarantee to suport them, thereby violating substituability. This is private inheritance and is usually used only for programming implementation puproposes.

在 UML 元模型中挖掘一点,泛化似乎有一个 isSubstitutable 属性,默认情况下为真。所以你可以考虑使用你自己的特定语言 profile,并在其中定义一个构造型 «Private inheritance»«Protected inheritance» 来专门化 Generalization 元模型元素,都带有 isSubstituable=false。这将允许:

这可能是传达您的语言特定设计意图的一种非常实用且可读的方式,包括 D1 对象不能替代 B1。但请注意,这并非没有风险:isSubsituable 只是关于 运行 的时间承诺,实际上对 UML 中 public 特性的继承规则没有影响。因此,自动化工具可能会得出与您的读者不同的结论(这就是我在上面提出另一种方法的原因)。

我会说 UML 通常是它所具有的关系类型,例如一对一或一对多。如果您是从抽象 class、接口或另一个基础 class 派生的。通常在继承过程中,您会使用 protected 关键字,这样所有内容对于继承之外的任何 class 都是私有的。 从基础 class 继承后,您还可以覆盖基础 class 的方法以及 运行 覆盖方法内部的基础方法。

我相信您在这里寻找的是 protected 关键字,它基本上是私有继承。只有相关 classes 才能访问此类成员。例如,您创建一个包含受保护成员的基 class,然后在继承的 class 或派生自该基的 class 中使用这些成员。 这是更多信息 https://www.tutorialspoint.com/cplusplus/cpp_inheritance.htm