0

我有一个零件列表,其中一些需要一个指向引擎的指针,我们称它们为 EngineParts。我想要的是使用 RTTI 找到这些 EngineParts,然后给他们引擎。

问题是如何设计EnginePart。我这里有两种选择,如下所述,我不知道该选择哪一种。选项 1 更快,因为它没有虚函数。如果我想 Clone() 对象,选项 2 更容易,因为没有数据它不需要 Clone() 函数。

有什么想法吗?也许还有第三种选择?

选项1:


class Part;

class EnginePart : public Part {
    protected: Engine *engine
    public: void SetEngine(Engine *e) {engine = e}
};

class Clutch : public EnginePart {
    // code that uses this->engine
}

选项 2:


class Part;

class EnginePart : public Part {
    public: virtual void SetEngine(Engine *e)=0;
};

class Clutch : public EnginePart {
    private: Engine *engine;
    public: void SetEngine(Engine *e) { engine = e; }
    // code that uses this->engine
}

(注意,实际情况涉及的有点多,我不能使用简单的解决方案,比如为EngineParts创建单独的列表)

谢谢

4

2 回答 2

0

现代编译器(大约在过去 10 年)中的虚拟功能非常快,尤其是对于桌面机器目标,并且该速度不应影响您的设计。

无论如何,您仍然需要一个克隆方法,如果您想从指针/引用复制到基,因为您必须允许(此时未知)派生类复制自己,包括实现细节,如 vtable 指针。(虽然如果你坚持使用一个编译器/实现,你可以基于它采取捷径,并且每次你想使用另一个编译器或想要升级你的编译器时重新评估它们。)

这样就摆脱了您列出的所有标准,因此您又回到了不知道如何选择的状态。但这很容易:选择对您来说最简单的一个。(也就是说,我不能根据这个虚构的例子说,但我怀疑这是第一个。)

于 2010-02-06T21:10:40.863 回答
0

太糟糕了,说“零件不能容纳引擎”的回复被删除了,因为这实际上是解决方案。

由于不需要完整的引擎,我找到了第三种方法:


class Part;

class EngineSettings {
    private:
        Engine *engine
        friend class Engine;
        void SetEngine(Engine *e) {engine = e}
    public:
        Value* GetSomeValue(params) { return engine->GetSomeValue(params); }
};

class Clutch : public Part, public EngineSettings {
    // code that uses GetSomeValue(params) instead of engine->GetSomeValue(params)
}

因为 GetSomeValue() 需要一些 Engine 无法知道的参数,所以它无法像在选项 1 和 2 中注入引擎指针那样“注入”这个值。(嗯..除非我还提供了一个虚拟 GetParams()) .

这将引擎从离合器中隐藏起来,并且几乎只给了我一种编码方式。

于 2010-02-07T04:07:15.867 回答