我正在编写一个游戏框架,我正在尝试概括和封装与渲染器类似的平台相关代码,以便它更容易移植。我正在努力实现这一目标,同时仍然使用框架的干净方式。我目前遇到静态变量和命名空间的问题......
// Renderer.h namespace Renderer { static IRenderer* g_pRenderer = NULL; static IRenderer* Get(void) { return g_pRenderer; } static IRenderer* CreateD3DRenderer() { g_pRenderer = new RendererD3D(); // Derived from IRenderer return g_pRenderer; } }
所以在我的main()
中,我可以调用CreateD3DRenderer()
并返回一个实例就好了; g_pRenderer
保持其值,因为它正在创建并在其函数范围内返回...但是,Renderer::Get()
返回NULL
。从'static'
的init中删除g_pRenderer
会导致在其他文件中使用时发生冲突。
发生了什么事?
答案 0 :(得分:2)
首先,参数列表中的void仅在C中是必需的。在C ++中,您只需编写Get()
。
至于主要问题,static
变量仅限于编译单元。由于您将它们放在标题中,因此会为包含它的每个编译单元(即每个cpp文件)创建一个单独的变量。删除static
部分时会出现错误,因为您有多个具有相同名称的变量,从而导致链接错误。
如果您希望在多个文件之间共享单个变量,请使用extern
。但是,这被认为是不好的做法。你最好不要重构,所以你不需要这样的全局变量。
答案 1 :(得分:2)
您应该将所有功能定义保留在.cpp
个文件中,而不是.h
正在发生的是,当以这种方式使用静态时,函数或变量仅限于.cpp
文件,这意味着每个g_pRenderer
文件中的.cpp
都不同。由于每个定义仅限于一个.cpp
文件,因此不会发生多重定义。
您需要将其删除才能使全局指针生效。您可以将静态保留在getter函数上,但我会删除它。您应该将函数和全局变量的定义移动到.cpp
文件,并在.h
中保留每个文件的声明。将变量声明为extern
。