Reputation: 21
I'm writing a game framework and I'm trying to generalize and encapsulate platform dependent code like the renderer so that it makes it a bit easier to port. I'm trying to accomplish this while still having a clean way of using the framework. I'm currently having a problem with static variables and 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; } }
So in my main()
, I can call CreateD3DRenderer()
and it returns an instance just fine; g_pRenderer
is holding its value since it's being created and returned within the scope of its function... However, Renderer::Get()
returns NULL
. Removing 'static'
from the init of g_pRenderer
causes clashes when used in other files.
What's going on?
Upvotes: 2
Views: 3271
Reputation: 31972
You should keep all definitions of functions in .cpp
files, instead of .h
What is happening is that when static is used in that fashion, the function or variable is restricted to that .cpp
file, which means that g_pRenderer
is different in each .cpp
file. Multiple definition doesnt happen since each definition is restricted to one .cpp
file.
You need to remove it to get your global pointer to work. You can keep the static on the getter function, but I would remove it. You should move the definition of the function and the global variable to a .cpp
file and keep just a declaration of each in the .h
. Declare the variable as extern
.
Upvotes: 2
Reputation: 39481
First off, void in an argument list is only necessary in C. In C++, you'd just write Get()
.
As for the main question, static
variables are restricted to the compilation unit. Since you put them in a header, this results in a separate variable being created for every compilation unit (i.e. every cpp file) where it is included. You get errors when you remove the static
part because then you have multiple variables with the same name, leading to a linking error.
If you want a single variable to be shared between multiple files, you use extern
. However, this is considered bad practice. You're better off refactoring so you don't need global variables like that.
Upvotes: 2