【发布时间】:2019-06-16 14:25:02
【问题描述】:
我正在检查一个关于私有继承的FAQ,我不太了解以下两个结论,有人可以解释一下吗?
在这两种情况下,用户(外人)都不能将 Car* 转换为 Engine* 吗?
私有继承变体允许 Car 的成员将 Car* 转换为 Engine*?
私有继承是组合的一种语法变体(AKA 聚合和/或 has-a)。
例如,“Car has-a Engine”关系可以表示为 简单的构图:
class Engine { public: Engine(int numCylinders); void start(); // Starts this Engine }; class Car { public: Car() : e_(8) { } // Initializes this Car with 8 cylinders void start() { e_.start(); } // Start this Car by starting its Engine private: Engine e_; // Car has-a Engine };“Car has-a Engine”关系也可以使用 私有继承:
class Car : private Engine { // Car has-a Engine public: Car() : Engine(8) { } // Initializes this Car with 8 cylinders using Engine::start; // Start this Car by starting its Engine };“私有继承”和“组合”有何相似之处?有 这两个变体之间的一些相似之处:
- 在这两种情况下,每个 Car 对象中都包含一个 Engine 成员对象
- 在这两种情况下,用户(外部人员)都不能将 Car* 转换为 Engine*
- 在这两种情况下,Car 类都有一个 start() 方法,该方法调用包含的 Engine 对象的 start() 方法。
还有几个区别:
- 如果您想包含 每辆车有几个引擎
- 私有继承变体可能引入不必要的多重继承
- 私有继承变体允许 Car 的成员将 Car* 转换为 Engine*
- 私有继承变体允许访问基类的受保护成员
- 私有继承变体允许 Car 覆盖 Engine 的虚函数
- 私有继承变体使得为 Car 提供一个 start() 方法变得更简单(20 个字符与 28 个字符相比),该方法只需调用引擎的 start() 方法
【问题讨论】:
-
遗漏了另一个区别:私有继承将强制使用 vtables。
-
@van dench 这不是必须的,基类可能没有虚函数。
-
我很确定构造函数仍然强制使用 vtables。
-
@vandench 构造函数不强制使用 vtable,只有虚拟方法(或虚拟继承)可以。
标签: c++