Question

OpenGL runs on a state-based system without declaring an objects, can you do the same in a C++ static library?

I have been using the sSingleton technique shown below:

static il_context& get()
{
    static il_context sSingleton;
    return sSingleton;
}
il_context(){}; // do nothing
~il_context(){}; // do nothing

However, my understanding is that you must declare it as a variable on startup:

il_context ilContext;

Is there a way to self-activate a singleton on a function call?

Was it helpful?

Solution

In your library, you can declare a global variable at namespace scope:

// In library.cpp
Context ctx;

void library_func()
{
    // Do something to ctx
}

If your library has multiple source files, you need to use the extern keyword to tell the compiler that ctx exists in a different translation unit:

// In library2.cpp
extern Context ctx;

void other_library_func()
{
    // Do something else to ctx
}

Alternatively, you can use a function (not publicly exposed in your library) to create ctx on first use (the so-called Meyers Singleton used in your example):

Context& get_context()
{
    static Context ctx;
    return ctx;
}

in which case the first line of your function implementations would call get_context():

void library_func()
{
    Context& ctx = get_context();
    // Do something to ctx
}

Either way, it goes without saying that getting all this right with multiple threads is a tricky business, requiring careful management to prevent two functions from modifying ctx at the same time.

My personal feeling is that having a hidden context singleton like this is more trouble than it's worth, and it is better to allow clients to pass around a Context pointer/reference themselves and manage its lifetime in the normal way. For something that can only have a single instance, have the constructor throw if an object already exists, or (better) use an assertion to indicate the programmer error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top