静态铸造在我的情况下是一个好的设计吗?

时间:2013-02-14 14:10:46

标签: c++ oop casting game-engine

我使用来自here的游戏状态管理器(简介,主菜单,游戏等)。但是有一个问题。一个非常简约的例子:

class cApp //manages the states and gives them access to window
{
public:
cApp (RenderWindow & ref) : window(ref) {}
void changeState(cState *);     //these function realy doesn't matter
void update();
void draw();

RenderWindow & window; //the same as in the article, this class not only manages state but gives them access to window etc

private:
std::vector <cState *> states;
}

州:

class cState
{
public:
cState(cApp * ptr) : app(ptr) {}
virtual void update() = 0;
virtual void draw() = 0;
protected:
cApp * app;
}

到目前为止一切都很好。问题是这是基本框架的一部分。所以cApp只是非常基础的,只能访问窗口。然而,可能存在用户想要在他的游戏中使用网络的情况。网络引擎不是单个状态的一部分,因此它必须处于更全局(即cApp)级别。

所以用户这样做:

class cNetworkedApp : public cApp
{
public:
cNetworkedApp(RenderWindow & ref1, NetworkEngine & ref2)
: networking(ref2), cApp(ref1)
NetworkEngine & networking; //initialized in cNetworkedApp constructor
}

class CharacterCreationState : public cState
{
 CharacterCreationState(cApp * ptr) : cState(ptr) {}
 //implement pure virtual functions
 void draw()
 {}
 void update()
  {
      //THE PROBLEM
      //the state needs to access the network engine so casting is required
      cNetworkedApp * ptr = static_cast<cNetworkedApp*>(app))
      ptr->networking.sendSomething();
  }
}

唯一明显的解决方案是包含cApp中可能包含的所有内容,但正如我所说,这是一个框架。当然,像物理引擎或声音引擎这样的引擎是你放入状态的东西,这不是问题,但网络系统之类的东西必须是所有州都可用的一个对象。并非每个应用都使用它。

我是否需要重新设计此代码,还是可以的?

1 个答案:

答案 0 :(得分:1)

您的cApp可能会保留一个多态类型Engine的命名列表,即map<string,Engine*>,然后,您的用户可能会询问cApp是否有给定的发动机。

NetworkEngine将是纯抽象Engine的子类。

更新

当处理指针我确定它是给定的专用类型时,你应该使用static_cast,当你想查询指针是否可以转换为你应该使用的类型{{1 }}

我,我自己,对第一种情况采用更安全的方法,我使用断言来保证类型可以在正常代码中使用dynamic_cast进行转换:

static_cast

只有Engine* fetchedEngine = cApp.fetch("network"); assert( dynamic_cast<NetworkEngine*>(fetchedEngine) != NULL ); NetworkEngine* network = static_cast<NetWorkEngine*>(fetchedEngine); 类型的对象应该放在“网络”名称上,但也许有人错误地放了其他东西,NetworkEngine会让我们更安全而不用担心开销。< / p>