2013-01-14 125 views
2

我正在编写一个游戏框架,我试图推广和封装与渲染器相关的平台相关代码,以便它使端口更容易一些。我试图做到这一点,同时仍然有一个干净的方式来使用框架。我目前具有静态变量和命名空间的问题......命名空间中的静态变量

 
    // 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。在g_pRenderer的init中删除'static'会导致在其他文件中使用冲突。

发生了什么事?

回答

2

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

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

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

+0

我没有任何其他变量使用相同的名称。虽然在技术上,它包含了代码所在的头部后会重新声明,所以我非常理解。但除此之外,这是该程序中此名称的唯一变量。 – Sutanreyu

2

你应该保留的功能都定义在.cpp文件,而不是.h

正在发生的事情是,静态时以那种方式被使用,函数或变量都被限制到.cpp文件,这意味着g_pRenderer在每个.cpp文件中不同。由于每个定义限制为一个.cpp文件,所以不会发生多重定义。

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