fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <string>
  4. #include <map>
  5.  
  6. struct Base
  7. {
  8. static std::shared_ptr<Base> Create(int params)
  9. {
  10. std::cout << "Creating Base with params = " << params << "\n";
  11. return std::make_shared<Base>();
  12. }
  13. };
  14.  
  15. namespace Utility
  16. {
  17. struct FactoryToolBase
  18. {
  19. virtual std::shared_ptr<Base> Create(int params) = 0;
  20. };
  21.  
  22. template<typename T> struct FactoryTool: FactoryToolBase
  23. {
  24. std::shared_ptr<Base> Create(int params)
  25. {
  26. return T::Create(params);
  27. }
  28. };
  29.  
  30. struct Factory
  31. {
  32. std::map<std::string, std::unique_ptr<FactoryToolBase>> tools;
  33.  
  34. template<typename T> Factory& Register(std::string name)
  35. {
  36. tools[name] = std::unique_ptr<FactoryToolBase>(new FactoryTool<T>);
  37. return *this;
  38. }
  39.  
  40. std::shared_ptr<Base> Create(std::string name, int params)
  41. {
  42. return tools[name]->Create(params);
  43. }
  44. };
  45. }
  46.  
  47. namespace Trivial
  48. {
  49. struct Derived: Base
  50. {
  51. static std::shared_ptr<Base> Create(int params)
  52. {
  53. if (params == 0)
  54. {
  55. return Base::Create(params);
  56. }
  57. else
  58. {
  59. std::cout << "Creating Derived with params = " << params << std::endl;
  60. return std::make_shared<Derived>();
  61. }
  62. }
  63. };
  64. }
  65.  
  66. namespace Complex
  67. {
  68. template<typename T> struct Inherited
  69. {
  70. static std::shared_ptr<Base> Create(int params)
  71. {
  72. return T::Create(params);
  73. }
  74. };
  75.  
  76. struct Derived: Base, Inherited<Base>
  77. {
  78. static std::shared_ptr<Base> Create(int params)
  79. {
  80. if (params == 0)
  81. {
  82. return Inherited::Create(params);
  83. }
  84. else
  85. {
  86. std::cout << "Creating Derived with params = " << params << std::endl;
  87. return std::make_shared<Derived>();
  88. }
  89. }
  90. };
  91.  
  92. struct EvenMoreDerived: Base, Inherited<Derived>
  93. {
  94. static std::shared_ptr<Base> Create(int params)
  95. {
  96. if (params < 1000)
  97. {
  98. return Inherited::Create(params);
  99. }
  100. else
  101. {
  102. std::cout << "Creating EvenMoreDerived with params = " << params << std::endl;
  103. }
  104. }
  105. };
  106. }
  107.  
  108. int main()
  109. {
  110. std::cout << "Trivial static inheritance" << std::endl;
  111. Utility::Factory trivial;
  112. trivial
  113. .Register<Base>("Base")
  114. .Register<Trivial::Derived>("Derived");
  115. trivial.Create("Base", 123); // -> Base::Create(123)
  116. trivial.Create("Derived", 0); // -> Base::Create(0)
  117. trivial.Create("Derived", 123); // -> Derived::Create(123)
  118.  
  119. std::cout << std::endl << "Complex static inheritance" << std::endl;
  120. Utility::Factory complex;
  121. complex
  122. .Register<Base>("Base")
  123. .Register<Complex::Derived>("Derived")
  124. .Register<Complex::EvenMoreDerived>("EvenMoreDerived");
  125. complex.Create("Base", 123); // -> Base::Create(123)
  126. complex.Create("Derived", 0); // -> Base::Create(0)
  127. complex.Create("Derived", 123); // -> Derived::Create(123)
  128. complex.Create("EvenMoreDerived", 0); // -> Base::Create(0)
  129. complex.Create("EvenMoreDerived", 123); // -> Derived::Create(123)
  130. complex.Create("EvenMoreDerived", 1234); // -> EvenMorederived::Create(1234)
  131.  
  132. return 0;
  133. }
Success #stdin #stdout 0s 3484KB
stdin
Standard input is empty
stdout
Trivial static inheritance
Creating Base with params = 123
Creating Base with params = 0
Creating Derived with params = 123

Complex static inheritance
Creating Base with params = 123
Creating Base with params = 0
Creating Derived with params = 123
Creating Base with params = 0
Creating Derived with params = 123
Creating EvenMoreDerived with params = 1234