假设我有以下类结构:
class Car; class FooCar : public Car; class BarCar : public Car; class Engine; class FooEngine : public Engine; class BarEngine : public Engine;
我们也给它Car
一个句柄Engine
.FooCar
将使用a创建A ,FooEngine*
并使用a BarCar
创建BarEngine*
.有没有办法安排事情,所以一个FooCar
对象可以调用成员函数而FooEngine
无需向下转换?
这就是为什么类结构按照现在的方式布局的原因:
所有人Car
都有Engine
.此外,一个FooCar
只会使用一个FooEngine
.
所有人都共享数据和算法Engine
,我宁愿不复制和粘贴.
我可能想写一个需要Engine
了解它的函数Car
.
一旦我dynamic_cast
在编写这段代码时输入,我就知道我可能做错了什么.有一个更好的方法吗?
更新:
根据目前给出的答案,我倾向于两种可能性:
有Car
提供一个纯虚getEngine()
函数.这将允许FooCar
并BarCar
具有返回正确类型的实现Engine
.
将所有Engine
功能吸收到Car
继承树中. Engine
因维护原因而被打破(将这些Engine
东西放在一个单独的地方).这是在拥有更多小类(代码行数较少)与较少大类之间的权衡.
是否有强烈的社区偏好这些解决方案之一?我还没有考虑过第三种选择吗?
我假设Car拥有一个引擎指针,这就是为什么你会发现自己的低迷.
将指针从基类中取出,并将其替换为纯虚拟get_engine()函数.然后你的FooCar和BarCar可以保持指向正确引擎类型的指针.
(编辑)
为什么这样有效:
由于虚函数Car::get_engine()
将返回引用或指针,因此C++将允许派生类使用不同的返回类型实现此函数,只要返回类型仅因更多派生类型而不同.
这称为协变返回类型,并允许每种Car
类型返回正确的Engine
.
我只想补充一点:这个设计对我来说已经闻起来很糟糕,因为我称之为并行树.
基本上,如果您最终得到并行类层次结构(就像您使用Car和Engine一样),那么您只是在寻找麻烦.
如果Engine(甚至是Car)需要有子类,或者那些只是相同的基类的不同实例,我会重新考虑.
您还可以按如下方式对引擎类型进行模板化
templateclass Car { protected: EngineType* getEngine() {return pEngine;} private: EngineType* pEngine; }; class FooCar : public Car class BarCar : public Car