【问题标题】:Designing classes for inheritance为继承设计类
【发布时间】:2012-05-22 01:58:30
【问题描述】:

假设我有一个实体类。
然后我有 n 个从 Entity
派生的类 例如:

class Snake : public Entity{...};  
class Mouse : public Entity{...};

现在我有一个作为实体的职业玩家。
我可以创建一个继承自任何类型实体的类播放器吗? 例如:

class Player : public Entity -->(but instead of entity be any type of entity)  

这样可以吗?
这是通过使用模板实现的吗?
我读过可以在 cpp 文件中明确指定模板,即

template class Entity<Snake>;

我正在努力实现以下目标

在我的玩家类中,我有一个 moveCamera 函数,现在只有当玩家移动时,相机才会移动。如果 AI Snake 移动,相机不应该移动。

这是我在虚拟实体类中的渲染函数

void Entity::Render(float interpolation)
{
  if(currentAnimation != 0){
    float x = this->currLocation.x - (this->currentVelocity.x * (1.0f - interpolation)) - camera->getLocation(L_FACTOR_CURRENT).x;
    float y = this->currLocation.y - (this->currentVelocity.y * (1.0f - interpolation)) - camera->getLocation(L_FACTOR_CURRENT).y;
    currentAnimation->Render(x,y);
  }
}

这是我的 gameUpdate 函数,基本上将实体移动到其各自的世界坐标

void Entity::GameUpdate(float gameUpdateDelta)
{
  this->Move();
}

因此对于我的播放器的移动函数我会调用相机的移动函数然后调用基类的移动函数...现在可以调用基类移动函数的扩展类..
我的 Move 功能是虚拟的,因此蛇和鼠标的移动方式不同..

【问题讨论】:

  • 你为什么要这样做?似乎您需要组合,而不是继承?看看Decorator pattern - 可能会有所帮助
  • 让玩家拥有一个实体(蛇/鼠标)。在处理玩家输入的函数中,您将调用 Player 中的函数(例如 move),该函数将处理相机移动并调用 Entity 中的移动函数。对于 AI,直接调用移动函数即可。一般来说,抽象出任何特定于人类玩家(或 AI 实现)的东西,但在 Entity 中保留类似的接口(和实现)。在 Player 类(或 AI 类)中实现那些特定的东西。
  • 我如何使用装饰器模式做同样的事情?
  • 可以使用模板,但在这种情况下,您要寻找的是一个概念,它不是 C++ 的一部分。相反,Entity 成为您在模板中调用的一组临时成员函数 - 它没有在语言中编码。但在大多数情况下,组合更好的解决方案。
  • 这个实现对我正在尝试的东西有什么缺点?

标签: c++ templates inheritance


【解决方案1】:

你可能想写一个模板类Player,继承自模板参数。

template< typename Derived >
class Player: 
    public Derived, // we believe that Derived inherits Entity
    public IPlayer  // makes sense if Player is not a Entity only interface
{
   ... some declaration here ...

   void update(); // some virtual method from Entity interaface
   void player_action(); // some virtual method from IPlayer interaface

}

在创建具体类型的播放器时,您可以将其放置在您的场景中。

IPlayer* player1 = new  Player<Snake>("Player1");

Entity* playerEntity = dynamic_cast< Entity* >( player1 );
if( playerEntity ) // test if object can be placed on scene
{
    scene->add( playerEntity );
}

您可能还需要知道如何编写类方法的部分模板特化。 您还可以发现boost enable_if 是一个强大的玩具。

【讨论】:

  • 你能详细说明 IPlayer 可以做什么吗?接口函数名称的一些示例..
  • 任何你需要操纵播放器,但不需要实体。像getCurretScore() 或一些输入句柄。
【解决方案2】:

如果您可以发布当前设计的接口(仅是类定义),对人们的帮助会更有帮助。看起来你需要让玩家自己的蛇和老鼠。如果您希望某些操作与其他操作相关联,请使用观察者。

【讨论】:

    猜你喜欢
    • 2023-01-12
    • 2012-08-10
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 2018-10-23
    相关资源
    最近更新 更多