fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <stdexcept>
  4.  
  5. //Some made up configuration data for a Foo class.
  6. struct FooConfig
  7. {
  8. int i;
  9. double d;
  10. };
  11.  
  12. //Some made up configuration data for a Bar class.
  13. struct BarConfig
  14. {
  15. int x;
  16. double y;
  17. };
  18.  
  19. //Configurations can be shared among classes.
  20. struct SharedConfig
  21. {
  22. std::string text;
  23. };
  24.  
  25. //The actual wrapper.
  26. template <class T>
  27. class StaticConfig
  28. {
  29. public:
  30.  
  31. StaticConfig()
  32. {
  33. if (!mIsInitialised)
  34. {
  35. throw std::runtime_error("Tried to construct uninitialised StaticConfig!");
  36. }
  37. }
  38.  
  39. const T*
  40. operator -> () const
  41. {
  42. return &mConfig;
  43. }
  44.  
  45. private:
  46.  
  47. friend class ConfigHandler;
  48.  
  49. StaticConfig(const T& config)
  50. {
  51. mConfig = config;
  52. mIsInitialised = true;
  53. }
  54.  
  55. static T mConfig;
  56. static bool mIsInitialised;
  57. };
  58.  
  59. template <class T>
  60. T StaticConfig<T>::mConfig;
  61. template <class T>
  62. bool StaticConfig<T>::mIsInitialised = false;
  63.  
  64. //ConfigHandler responsible for loading the data.
  65. class ConfigHandler
  66. {
  67. public:
  68.  
  69. ConfigHandler() :
  70. mFooConfig(GetFooConfig()),
  71. mBarConfig(GetBarConfig()),
  72. mSharedConfig(GetSharedConfig())
  73. {}
  74.  
  75. FooConfig
  76. GetFooConfig()
  77. {
  78. FooConfig fooConfig;
  79. fooConfig.i = 1337;
  80. fooConfig.d = 123.45;
  81. return fooConfig;
  82. }
  83.  
  84. BarConfig
  85. GetBarConfig()
  86. {
  87. BarConfig barConfig;
  88. barConfig.x = 69;
  89. barConfig.y = 987.65;
  90. return barConfig;
  91. }
  92.  
  93. SharedConfig
  94. GetSharedConfig()
  95. {
  96. SharedConfig sharedConfig;
  97. sharedConfig.text = "This is a std::string!";
  98. return sharedConfig;
  99. }
  100.  
  101. private:
  102.  
  103. StaticConfig<FooConfig> mFooConfig;
  104. StaticConfig<BarConfig> mBarConfig;
  105. StaticConfig<SharedConfig> mSharedConfig;
  106. };
  107.  
  108. class Foo
  109. {
  110. public:
  111.  
  112. void
  113. Print()
  114. {
  115. std::cout << "Foo prints " << mConfig->i << " " << mConfig->d << " "
  116. << mSharedConfig->text << '\n';
  117. }
  118.  
  119. private:
  120.  
  121. StaticConfig<FooConfig> mConfig;
  122. StaticConfig<SharedConfig> mSharedConfig;
  123. };
  124.  
  125. class Bar
  126. {
  127. public:
  128.  
  129. void
  130. Print()
  131. {
  132. std::cout << "Bar prints " << mConfig->x << " " << mConfig->y << " "
  133. << mSharedConfig->text << '\n';
  134. }
  135.  
  136. private:
  137.  
  138. StaticConfig<BarConfig> mConfig;
  139. StaticConfig<SharedConfig> mSharedConfig;
  140. };
  141.  
  142. int main()
  143. {
  144. //If uncommented, this next line throws as it attempts to...
  145. //...construct a StaticConfig<FooConfig> inside foo before...
  146. //...ConfigHandler has a chance to initialise things.
  147. //Foo aFoo;
  148.  
  149. //ConfigHandler must only briefly exist to load data.
  150. ConfigHandler();
  151. Foo foo;
  152. Bar bar;
  153.  
  154. foo.Print();
  155. bar.Print();
  156.  
  157. return 0;
  158. }
  159.  
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Foo prints 1337 123.45 This is a std::string!
Bar prints 69 987.65 This is a std::string!