c++ - 在我的情况下静态类型转换是一个好的设计吗?

标签 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 中可能的所有内容,但正如我所说,这是一个框架。当然,某些引擎(例如物理引擎或声音引擎)是您放入某个状态的东西,所以这不是问题,但是网络系统之类的东西必须是所有状态都可用的一个对象。并非每个应用程序都使用它。

我需要重新设计这段代码吗?

最佳答案

你的 cApp可以保留一个多态类型的命名列表 Engine ,即map<string,Engine*> ,然后,您的用户可能会询问 cApp如果它有给定的引擎。

NetworkEngine将是纯抽象的子类 Engine .

更新

当处理一个你确定它属于给定特殊类型的指针时,你应该使用static_cast , 当你想查询指针是否可以转换为你应该使用的类型时 dynamic_cast .

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

Engine* fetchedEngine = cApp.fetch("network");
assert( dynamic_cast<NetworkEngine*>(fetchedEngine) != NULL );
NetworkEngine* network = static_cast<NetWorkEngine*>(fetchedEngine);

只有 NetworkEngine 类型的对象应该放在“网络”名称上,但也许有人错误地放了别的东西,assert将使我们更安全,而无需担心开销。

关于c++ - 在我的情况下静态类型转换是一个好的设计吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14876707/

相关文章:

c# - 如何摆脱虚拟表?密封类

c++ - 原始构造函数与转换转换

java - double 等于一个整数总是会转换为该整数吗?

c++ - 如何避免在提升范围变换中复制

c++ - ActiveMq:持久队列和离线系统

php - 如何在其他类中使用PDO连接?

c# - 如何以更清洁的方式处理大型工厂

c++ - 从 C++ 返回对对象的引用时,是否需要在返回变量中使用 "&"运算符?

c++ - 迭代时删除集合元素///

c# - 如何检查 Func<...> 类型的变量是否是特定的类方法