fork(1) download
  1. #include <iostream>
  2. #include <memory>
  3. #include <vector>
  4.  
  5. using namespace std;
  6.  
  7.  
  8. /////////////////////////////////////////
  9. // opengl_helper.h
  10. // this is some manager class that knows what should be initialized later
  11. struct OpenGLHelper
  12. {
  13. typedef std::function<void()> function_type;
  14.  
  15. static void register_initializer(function_type fn);
  16.  
  17. static std::vector<function_type> *initializer_list;
  18.  
  19. static void run_init();
  20. };
  21. // helper class that will register some function at construction time
  22. struct OpenGLHelper_initializer
  23. {
  24. OpenGLHelper_initializer(OpenGLHelper::function_type fn)
  25. {
  26. OpenGLHelper::register_initializer(fn);
  27. }
  28. };
  29. /////////////////////////////////////////
  30. //opengl_helper.cpp
  31. // static pointer to a list
  32. // it will be initialized by nullptr when program loads
  33. // this is important to use raw pointer as it does not need to call any constructor
  34. std::vector<OpenGLHelper::function_type> *OpenGLHelper::initializer_list = nullptr;
  35.  
  36. // function that puts initializer into a list.
  37. void OpenGLHelper::register_initializer(OpenGLHelper::function_type fn)
  38. {
  39. if (!initializer_list)
  40. initializer_list = new std::vector<OpenGLHelper::function_type>;
  41.  
  42. initializer_list->push_back(fn);
  43. }
  44.  
  45. void OpenGLHelper::run_init()
  46. {
  47. if (initializer_list)
  48. {
  49. for (auto fn : *initializer_list)
  50. fn();
  51. }
  52. }
  53.  
  54. /////////////////////////////////////////
  55. // figure.h
  56. // here is sample class that will be registered for initialization
  57. struct Square
  58. {
  59. static int to_be_initialized;
  60.  
  61. // static member that will register Square class to be initialized
  62. static OpenGLHelper_initializer __initializer;
  63. };
  64.  
  65. /////////////////////////////////////////
  66. // Square.cpp
  67. int Square::to_be_initialized = 0;
  68. // this is the most interesting part - register square into initializer list
  69. OpenGLHelper_initializer Square::__initializer([](){
  70. Square::to_be_initialized = 15;
  71. std::cout << "Called Square::init: " << to_be_initialized << std::endl;
  72. });
  73.  
  74. int main()
  75. {
  76. std::cout << "Before initialization : " << Square::to_be_initialized << std::endl;
  77. OpenGLHelper::run_init();
  78. std::cout << "After initialization : " << Square::to_be_initialized << std::endl;
  79. return 0;
  80. }
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
Before initialization : 0
Called Square::init: 15
After  initialization : 15