C ++如果对象属于某种类型,则禁止某些函数

时间:2017-08-31 03:01:38

标签: c++ polymorphism

我有一个奇怪的生活质量问题:

Entity* Bob = new Camera其中Entity(abstract)是我在矢量数组中想要的一种对象。而相机是特定的对象。

我没有问题让Camera继承并实现Entity的功能到相机。相机运行正常。当我使用Entity* Joe = new Cube;

创建另一个对象时,会出现问题

现在我希望能够将Joe和Bob组合在一起,但Bob是一个移动对象,我希望他继承ProcessKeyboard();函数,所以我可以在使用Bob时使用它。但是Joe没有动,所以我甚至没有Joe能够访问ProcessKeyboard();功能。

现在,我可以让Joe的ProcessKeyboard功能什么都不做,但我宁愿编译器不允许我将它作为Joe的选项来呈现。

我认为我的主要问题是我应该如何解决这个问题?

1 个答案:

答案 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,但在这种特殊情况下,它听起来像最后决定 ......