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

C++ 在我的情况下,静态铸造是一个好的设计吗?,c++,oop,casting,game-engine,C++,Oop,Casting,Game Engine,我从中使用游戏状态管理器(介绍、主菜单、游戏性等)。然而,有一个问题。一个非常简单的例子: 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()

我从中使用游戏状态管理器(介绍、主菜单、游戏性等)。然而,有一个问题。一个非常简单的例子:

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;
}
到目前为止一切都很好。问题是这是基本框架的一部分。因此,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();
  }
}
class CNNetworkedApp:公共cApp
{
公众:
CNNetworkedApp(渲染窗口和参考1,网络引擎和参考2)
:网络(参考文献2),cApp(参考文献1)
NetworkEngine&networking;//在cNetworkedApp构造函数中初始化
}
类字符CreationState:公共cState
{
CharacterCreationState(cApp*ptr):cState(ptr){}
//实现纯虚拟函数
作废提款()
{}
无效更新()
{
//问题
//该状态需要访问网络引擎,因此需要强制转换
cNetworkedApp*ptr=静态(应用程序))
ptr->networking.sendSomething();
}
}
唯一明显的解决方案是在cApp中包含所有可能的内容,然而正如我所说的,这是一个框架。当然,有些引擎,如物理引擎或声音引擎,是你放入状态的东西,所以这不是问题,但像网络系统这样的东西必须是所有状态的唯一可用对象。并不是每个应用都使用它


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

您的
cApp
可能会附带一个多态类型
引擎的命名列表,即
map
,然后,您的用户可能会询问
cApp
是否有给定的引擎

NetworkEngine
将是纯抽象
引擎的子类

更新 当处理一个指针时,如果你确定它是给定的专用类型,你应该使用
static\u cast
,当你想查询指针是否可以被强制转换为一个你应该使用
dynamic\u cast
的类型时

一、 对于第一种情况,我自己有一个更安全的方法,我使用断言来保证类型可以被强制转换,并在普通代码中使用
static\u cast

Engine* fetchedEngine = cApp.fetch("network");
assert( dynamic_cast<NetworkEngine*>(fetchedEngine) != NULL );
NetworkEngine* network = static_cast<NetWorkEngine*>(fetchedEngine);
Engine*fetchedEngine=cApp.fetch(“网络”);
断言(动态转换(fetchedEngine)!=NULL);
NetworkEngine*network=static\u cast(fetchedEngine);

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

动态\u cast
甚至不起作用,因为类不是多态的。请花点时间编写问题中的正确代码。按照目前的情况,基的定义无法编译。虽然在阅读时可以修复小错误,但在这种特殊情况下,不清楚基类型中的任何成员函数是否应该虚拟地更改代码。现在好了。(我想)@user1873947:不,不是。@davidrodríguez那么wrog是什么?尽管这是一个伪代码。有趣的方法。您是对的,将状态管理器与引擎分离是一个很好的解决方案。我将拭目以待,看看是否有人有其他有趣的解决方案。使用这种方法,我应该更喜欢动态_cast还是静态_cast?@user1873947编辑了我的答案,请看一看look@user1873947请注意,要进行动态转换工作,您需要一个vtable。只要创建一个虚拟析构函数,就完成了。
Engine* fetchedEngine = cApp.fetch("network");
assert( dynamic_cast<NetworkEngine*>(fetchedEngine) != NULL );
NetworkEngine* network = static_cast<NetWorkEngine*>(fetchedEngine);