命名空间中的静态变量

时间:2013-01-14 05:17:35

标签: c++ static namespaces

我正在编写一个游戏框架,我正在尝试概括和封装与渲染器类似的平台相关代码,以便它更容易移植。我正在努力实现这一目标,同时仍然使用框架的干净方式。我目前遇到静态变量和命名空间的问题......

    // 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会导致在其他文件中使用时发生冲突。

发生了什么事?

2 个答案:

答案 0 :(得分:2)

首先,参数列表中的void仅在C中是必需的。在C ++中,您只需编写Get()

至于主要问题,static变量仅限于编译单元。由于您将它们放在标题中,因此会为包含它的每个编译单元(即每个cpp文件)创建一个单独的变量。删除static部分时会出现错误,因为您有多个具有相同名称的变量,从而导致链接错误。

如果您希望在多个文件之间共享单个变量,请使用extern。但是,这被认为是不好的做法。你最好不要重构,所以你不需要这样的全局变量。

答案 1 :(得分:2)

您应该将所有功能定义保留在.cpp个文件中,而不是.h

正在发生的是,当以这种方式使用静态时,函数或变量仅限于.cpp文件,这意味着每个g_pRenderer文件中的.cpp都不同。由于每个定义仅限于一个.cpp文件,因此不会发生多重定义。

您需要将其删除才能使全局指针生效。您可以将静态保留在getter函数上,但我会删除它。您应该将函数和全局变量的定义移动到.cpp文件,并在.h中保留每个文件的声明。将变量声明为extern