当前位置:  开发笔记 > 编程语言 > 正文

如何在C++代码中避免使用dynamic_cast?

如何解决《如何在C++代码中避免使用dynamic_cast?》经验,为你挑选了3个好方法。

假设我有以下类结构:

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()函数.这将允许FooCarBarCar具有返回正确类型的实现Engine.

    将所有Engine功能吸收到Car继承树中. Engine因维护原因而被打破(将这些Engine东西放在一个单独的地方).这是在拥有更多小类(代码行数较少)与较少大类之间的权衡.

是否有强烈的社区偏好这些解决方案之一?我还没有考虑过第三种选择吗?



1> Drew Dormann..:

我假设Car拥有一个引擎指针,这就是为什么你会发现自己的低迷.

将指针从基类中取出,并将其替换为纯虚拟get_engine()函数.然后你的FooCar和BarCar可以保持指向正确引擎类型的指针.

(编辑)

为什么这样有效:

由于虚函数Car::get_engine()将返回引用或指针,因此C++将允许派生类使用不同的返回类型实现此函数,只要返回类型仅因更多派生类型而不同.

这称为协变返回类型,并允许每种Car类型返回正确的Engine.


由于虚函数允许协变返回类型,因此您可以使返回的值为适当的FooEngine或BarEngine类型!我忽略了这个简单解决方案的+1.

2> cletus..:

我只想补充一点:这个设计对我来说已经闻起来很糟糕,因为我称之为并行树.

基本上,如果您最终得到并行类层次结构(就像您使用Car和Engine一样),那么您只是在寻找麻烦.

如果Engine(甚至是Car)需要有子类,或者那些只是相同的基类的不同实例,我会重新考虑.


你能提供一个具体的例子(根据上面我的类结构)如何解决"并行树"问题?

3> JohnMcG..:

您还可以按如下方式对引擎类型进行模板化

template
class Car
{
    protected:
        EngineType* getEngine() {return pEngine;}
    private:
        EngineType* pEngine;
};

class FooCar : public Car

class BarCar : public Car

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有