fork download
  1. #include <memory>
  2. #include <string>
  3. #include <iostream>
  4.  
  5.  
  6.  
  7.  
  8. struct Base{
  9.  
  10. protected:
  11.  
  12.  
  13. virtual std::shared_ptr<Base> clone_impl() const{
  14. return std::make_shared<Base>(*this);
  15. };
  16.  
  17. public:
  18.  
  19. std::shared_ptr<Base> clone()const{
  20. return clone_impl();
  21. }
  22.  
  23.  
  24. std::string DoBase(){ return "Base"; }
  25.  
  26. virtual std::string Name(){ return DoBase(); }
  27.  
  28. };
  29. template<class D, class B>
  30. struct clonable:public B{
  31. virtual std::shared_ptr<B> clone_impl() const override{
  32. return std::make_shared<D>(static_cast<const D&>(*this));
  33. }
  34.  
  35. std::shared_ptr<D> clone()const{
  36. return std::static_pointer_cast<D>(clone_impl());
  37. }
  38.  
  39. };
  40.  
  41.  
  42. struct Derived : public clonable<Derived,Base>{
  43.  
  44. std::string DoDerived(){ return "Derived"; }
  45.  
  46. virtual std::string Name()override{ return DoDerived(); }
  47.  
  48.  
  49. };
  50.  
  51.  
  52.  
  53. struct Derived2 : public clonable<Derived2, Base>{
  54.  
  55. std::string DoDerived2(){ return "Derived2"; }
  56.  
  57. virtual std::string Name() override{ return DoDerived2(); }
  58. };
  59.  
  60.  
  61. int main(){
  62. {
  63. auto spD = std::make_shared<Derived>();
  64.  
  65. std::shared_ptr<Base> spB = spD;
  66.  
  67. auto clonedB = spB->clone();
  68.  
  69. auto clonedD = spD->clone();
  70.  
  71. std::cout << clonedB->DoBase() << "\n";
  72. std::cout << clonedD->DoDerived() << "\n";
  73. std::cout << clonedB->Name() << "\n";
  74. }
  75.  
  76. {
  77.  
  78. auto spD = std::make_shared<Derived2>();
  79.  
  80. std::shared_ptr<Base> spB = spD;
  81.  
  82. auto clonedB = spB->clone();
  83.  
  84. auto clonedD = spD->clone();
  85.  
  86. std::cout << clonedB->DoBase() << "\n";
  87. std::cout << clonedD->DoDerived2() << "\n";
  88. std::cout << clonedB->Name() << "\n";
  89. }
  90.  
  91. }
Success #stdin #stdout 0s 3032KB
stdin
Standard input is empty
stdout
Base
Derived
Derived
Base
Derived2
Derived2