我有一个部件列表,其中一些需要指向引擎的指针,我们称之为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创建单独列表这样的简单解决方案)
由于
答案 0 :(得分:0)
现代编译器中的虚拟功能(大约过去10年)非常快,特别是对于台式机目标而言,速度不应该影响您的设计。
如果你想从指针/引用到基类复制,你仍然需要克隆方法,因为你必须允许(此时未知)派生类自我复制,包括实现细节,如vtable指针。 (虽然如果你坚持使用一个编译器/实现,你可以根据它来获取快捷方式,并且每次你想要使用另一个编译器或想要升级你的编译器时重新评估它们。)
这摆脱了你列出的所有标准,所以你又不知道如何选择。但这很容易:选择最简单的方法。 (也就是说,我不能说基于这个组成的例子,但我怀疑它是第一个。)
答案 1 :(得分: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()需要一些引擎无法知道的参数,所以它无法“注入”这个值,就像在选项1和2中注入了引擎指针一样。(好吧..除非我还提供虚拟的GetParams ())。
这隐藏了离合器的引擎,并且只给我一种编码方式。