我有一个奇怪的生活质量问题:
Entity* Bob = new Camera
其中Entity(abstract)是我在矢量数组中想要的一种对象。而相机是特定的对象。
我没有问题让Camera继承并实现Entity的功能到相机。相机运行正常。当我使用Entity* Joe = new Cube;
现在我希望能够将Joe和Bob组合在一起,但Bob是一个移动对象,我希望他继承ProcessKeyboard();
函数,所以我可以在使用Bob时使用它。但是Joe没有动,所以我甚至没有Joe能够访问ProcessKeyboard();
功能。
现在,我可以让Joe的ProcessKeyboard功能什么都不做,但我宁愿编译器不允许我将它作为Joe的选项来呈现。
我认为我的主要问题是我应该如何解决这个问题?
答案 0 :(得分:0)
我认为最合乎逻辑的解决方案是:
class Entity
{
virtual void Update() = 0;
}
class Camera : public Entity
{
void Update() override {
// ...
}
void ProcessKeyboard() {
// ...
}
}
class Cube : public Entity
{
void Update() override {
// ...
}
}
然后分别存储实体和相机:
vector<Entity*> entities; // pointers to all your entities are here
vector<Camera*> cameras; // additionally track Camera objects
for(auto entity : entities) {
entity->Update();
}
for(auto camera : cameras) {
camera->ProcessKeyboard();
}
...我希望他继承ProcessKeyboard();功能,所以我可以使用 它在使用Bob时。
如您所见,为了使用ProcessKeyboard()
,您不需要继承它;另外我必须说,因为ProcessKeyboard()
不是virtual
,所以没有涉及额外的vtable(仅适用于Entity
),并且ProcessKeyboard()
调用不会进行vtable查找。这很好。
但是,如果有很多不同的“可移动”对象并且你并不关心性能那么多...... OOP风格的解决方案很明显:只需为可移动对象创建一个“接口”。
class IMovable
{
virtual void ProcessKeyboard() = 0;
}
class Camera : public Entity, public IMovable
{
void Update() override {
// ...
}
void ProcessKeyboard() override {
// ...
}
}
用法:
vector<Entity*> entities; // the same approach
vector<IMovable*> movable; // additionally track all movable objects
for(auto entity : entities) {
entity->Update();
}
for(auto object : movable) {
object ->ProcessKeyboard();
}
除了所说的一切之外,还有一个dynamic_cast
,但在这种特殊情况下,它听起来像最后决定 ......