#include <iostream>
#include <memory>
#include <vector>
using namespace std;
/////////////////////////////////////////
// opengl_helper.h
// this is some manager class that knows what should be initialized later
struct OpenGLHelper
{
typedef std::function<void()> function_type;
static void register_initializer(function_type fn);
static std::vector<function_type> *initializer_list;
static void run_init();
};
// helper class that will register some function at construction time
struct OpenGLHelper_initializer
{
OpenGLHelper_initializer(OpenGLHelper::function_type fn)
{
OpenGLHelper::register_initializer(fn);
}
};
/////////////////////////////////////////
//opengl_helper.cpp
// static pointer to a list
// it will be initialized by nullptr when program loads
// this is important to use raw pointer as it does not need to call any constructor
std::vector<OpenGLHelper::function_type> *OpenGLHelper::initializer_list = nullptr;
// function that puts initializer into a list.
void OpenGLHelper::register_initializer(OpenGLHelper::function_type fn)
{
if (!initializer_list)
initializer_list = new std::vector<OpenGLHelper::function_type>;
initializer_list->push_back(fn);
}
void OpenGLHelper::run_init()
{
if (initializer_list)
{
for (auto fn : *initializer_list)
fn();
}
}
/////////////////////////////////////////
// figure.h
// here is sample class that will be registered for initialization
struct Square
{
static int to_be_initialized;
// static member that will register Square class to be initialized
static OpenGLHelper_initializer __initializer;
};
/////////////////////////////////////////
// Square.cpp
int Square::to_be_initialized = 0;
// this is the most interesting part - register square into initializer list
OpenGLHelper_initializer Square::__initializer([](){
Square::to_be_initialized = 15;
std::cout << "Called Square::init: " << to_be_initialized << std::endl;
});
int main()
{
std::cout << "Before initialization : " << Square::to_be_initialized << std::endl;
OpenGLHelper::run_init();
std::cout << "After initialization : " << Square::to_be_initialized << std::endl;
return 0;
}