Sutanreyu
Sutanreyu

Reputation: 21

Static variable in a namespace

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

Answers (2)

Karthik T
Karthik T

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

Antimony
Antimony

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

Related Questions