我正在检查 FAQ关于private-inheritance,我不太理解以下两个结论,谁能解释一下?
在这两种情况下,用户(局外人)都不能将 Car* 转换为 Engine* 吗?
私有(private)继承变体允许 Car 的成员将 Car* 转换为 Engine*?
private inheritance is a syntactic variant of composition (AKA aggregation and/or has-a).
E.g., the “Car has-a Engine” relationship can be expressed using simple composition:
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 };
The “Car has-a Engine” relationship can also be expressed using private inheritance:
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 };
How are “private inheritance” and “composition” similar? There are several similarities between these two variants:
- In both cases there is exactly one Engine member object contained in every Car object
- In neither case can users (outsiders) convert a Car* to an Engine*
- In both cases the Car class has a start() method that calls the start() method on the contained Engine object.
There are also several distinctions:
- The simple-composition variant is needed if you want to contain several Engines per Car
- The private-inheritance variant can introduce unnecessary multiple inheritance
- The private-inheritance variant allows members of Car to convert a Car* to an Engine*
- The private-inheritance variant allows access to the protected members of the base class
- The private-inheritance variant allows Car to override Engine’s virtual functions
- The private-inheritance variant makes it slightly simpler (20 characters compared to 28 characters) to give Car a start() method that simply calls through to the Engine’s start() method
最佳答案
C++ 中private
关键字背后的动机是encapsulation -- 通过隐藏关于你的类的细节,编译器可以确保其他代码(在你的类自己的代码之外)不能也不依赖于这些细节,因此编译器帮助你保证其他代码不需要如果/当您将来更改这些详细信息时进行修改。
在这种情况下,如果您通过私有(private)继承派生子类,您就是在告诉编译器不应允许外部代码知道该继承。就外部代码而言,您的 Car
类和 Engine
类之间的关系不存在(除了作为他们不知道的实现细节关于)。另一方面,Car
类中的代码是“内部”代码,因此它会了解这种关系并在需要时利用它。这样一来,如果您更改关系(例如,如果您将 Car
更改为 Vehicle
而不是 Engine
的子类),您可能需要重写一些Car
类中的代码,但您不必出去修复其他任何依赖于 Car
子类 Engine 的代码
,因为从一开始就不允许外部代码依赖这种关系。
关于c++ - 为什么私有(private)继承对象允许成员函数将 derived* 强制转换为 base* 但外部人员不允许?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54319744/