为什么私有继承对象允许成员函数将派生的*转换为基*,而外部不能
Why private-inheritance object allows member function cast derived* to base* but outsiders not?
我正在查看一个关于私有继承的常见问题解答,我不太理解以下两个结论,有人能解释一下吗?
在这两种情况下,用户(外部人员)都不能将汽车*转换为发动机*
私有继承变体允许Car的成员将Car*转换为Engine*
私有继承是组合的句法变体(AKA聚集和/或has-a)。
例如,"汽车有发动机"的关系可以用简单组成:
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 };
"汽车有发动机"的关系也可以用私人继承:
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 };
"私人继承"answers"组合"有什么相似之处?有这两种变体之间的几个相似之处:
- 在这两种情况下,每个Car对象中都只包含一个Engine成员对象
- 在这两种情况下,用户(外部人员)都不能将汽车*转换为发动机*
- 在这两种情况下,Car类都有一个start()方法,该方法对包含的Engine对象调用start()
还有几个区别:
- 如果要包含每辆车几台发动机
- 私有继承变体可能会引入不必要的多重继承
- 私有继承变体允许Car的成员将Car*转换为Engine*
- 私有继承变体允许访问基类的受保护成员
- 私有继承变体允许Car覆盖Engine的虚拟功能
- 私有继承变体使为Car提供一个start()方法稍微简单一些(20个字符,而不是28个字符),该方法只调用Engine的start()
C++中private
关键字背后的动机是封装——通过隐藏类的详细信息,编译器可以确保其他代码(在类自己的代码之外)不能也不依赖于这些详细信息,因此编译器可以帮助您保证,如果/当您将来更改这些详细信息时,其他代码不需要修改。
在这种情况下,如果您是通过私有继承派生子类的,那么您就是在告诉编译器不应该允许外部代码知道该继承。就外部代码而言,Car
类和Engine
类之间的关系并不存在(除了他们不了解的实现细节)。另一方面,作为Car
类一部分的代码是"内部"代码,因此它可以了解这种关系并利用它(如果它想这样做的话)。这样,如果你改变了这种关系(例如,如果你将Car
从Vehicle
而不是Engine
改为子类),你可能必须重写Car
类中的一些代码,但您不必在其他地方修复任何依赖Car
子类Engine
的代码,因为外部代码从一开始就不允许依赖这种关系。
相关文章:
- 存储模板类型以强制转换回派生<T>
- 在 C++ 中将对象转换为派生类型
- 从基类实例调用派生类方法而不进行强制转换
- 从基指针到派生的强制转换问题
- C++将派生类转换为基类时'object slicing'期间发生的情况
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- C ++基础私有方法在将自身转换为派生类后可以访问吗?
- 调用不在基类中的派生类函数而不进行动态强制转换,以最大程度地提高性能
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 我们可以在不知道其真实类型的情况下将基类指针转换为派生类指针吗?
- 为什么从基转换为派生提供此功能?
- 将基本实例指针强制转换为派生实例指针是否合法?(实例不是派生实例)
- 从从该抽象类派生的 Python 对象强制转换C++抽象类C++
- 基类到派生类的强制转换向量
- 有没有办法复制派生类指针的向量而不将其强制转换为基类?
- 为什么此代码不将基类强制转换为 c++ 中的派生类?
- 如何在运行时将指向派生类的 void* 正确转换为指向基类的 void*
- C++转换派生类
- CRTP / 宏 / 避免强制转换派生类的指针
- 如何正确转换派生类