fork download
  1. #include <iostream>
  2.  
  3. struct Cloneable
  4. {
  5. protected:
  6. Cloneable(){}
  7. Cloneable(const Cloneable &){}
  8. public:
  9. virtual ~Cloneable(){}
  10.  
  11. Cloneable &operator=(const Cloneable &) = delete;
  12.  
  13. virtual Cloneable *Clone() const = 0;
  14. template<typename TextendsCloneable>
  15. static void ReleaseClone(TextendsCloneable *&clone)
  16. {
  17. Cloneable *c = dynamic_cast<Cloneable *>(clone);
  18. // if(!c) throw CloningException();
  19. clone = /*nullptr*/0;
  20. c->ReleaseClone(), c = /*nullptr*/0;
  21. }
  22. protected:
  23. virtual void ReleaseClone() = 0;
  24. public:
  25. // struct CloningException : public virtual Exception
  26. // {
  27. // CloningException(){}
  28. // CloningException(const char *msg) : Exception(msg) {}
  29. // CloningException(const CloningException &) = delete;
  30. // CloningException &operator=(const CloningException &) = delete;
  31. // virtual ~CloningException(){}
  32. // };
  33.  
  34. template<typename InheritingClass>
  35. struct Auto;
  36. };
  37.  
  38. template<typename InheritingClass>
  39. struct Cloneable::Auto : public virtual Cloneable
  40. {
  41. virtual Cloneable *Clone() const
  42. {
  43. const InheritingClass *t = dynamic_cast<const InheritingClass *>(this);
  44. if(!t)
  45. {
  46. // throw CloningException();
  47. }
  48. return new InheritingClass(*t);
  49. }
  50. protected:
  51. virtual void ReleaseClone()
  52. {
  53. if(!dynamic_cast<const InheritingClass *>(this))
  54. {
  55. // throw CloningException();
  56. }
  57. delete this;
  58. }
  59. public:
  60. virtual ~Auto(){}
  61. };
  62.  
  63. struct MyAbstractClass : public virtual Cloneable
  64. {
  65. MyAbstractClass(){}
  66. MyAbstractClass(const MyAbstractClass &){}
  67. virtual ~MyAbstractClass(){}
  68.  
  69. MyAbstractClass &operator=(const MyAbstractClass &) = delete;
  70.  
  71. virtual void Tick() = 0;
  72. };
  73.  
  74. struct MyImplementationClass : public virtual MyAbstractClass, public virtual Cloneable::Auto<MyImplementationClass>
  75. {
  76. MyImplementationClass(){}
  77. MyImplementationClass(const MyImplementationClass &){}
  78. virtual ~MyImplementationClass(){}
  79.  
  80. MyImplementationClass &operator=(const MyImplementationClass &) = delete;
  81.  
  82. virtual void Tick();
  83.  
  84. // using Cloneable::Auto<MyImplementationClass>::Clone;
  85. //protected:
  86. // using Cloneable::Auto<MyImplementationClass>::ReleaseClone;
  87. };
  88.  
  89. void MyImplementationClass::Tick()
  90. {
  91. std::cout << "Tick" << std::endl;
  92. }
  93.  
  94. int main()
  95. {
  96. MyImplementationClass a;
  97. MyAbstractClass *b = dynamic_cast<MyAbstractClass *>(a.Clone());
  98. b->Tick();
  99. Cloneable::ReleaseClone(b);
  100. }
  101.  
Success #stdin #stdout 0s 3020KB
stdin
Standard input is empty
stdout
Tick