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. protected:
  67. MyAbstractClass(const MyAbstractClass &){}
  68. public:
  69. virtual ~MyAbstractClass(){}
  70.  
  71. MyAbstractClass &operator=(const MyAbstractClass &) = delete;
  72.  
  73. virtual void Tick() = 0;
  74. };
  75.  
  76. struct MyImplementationClass : public virtual MyAbstractClass, public virtual Cloneable::Auto<MyImplementationClass>
  77. {
  78. MyImplementationClass(){}
  79. protected:
  80. MyImplementationClass(const MyImplementationClass &){}
  81. public:
  82. virtual ~MyImplementationClass(){}
  83.  
  84. MyImplementationClass &operator=(const MyImplementationClass &) = delete;
  85.  
  86. virtual void Tick();
  87.  
  88. using Cloneable::Auto<MyImplementationClass>::Clone;
  89. protected:
  90. using Cloneable::Auto<MyImplementationClass>::ReleaseClone;
  91. };
  92.  
  93. void MyImplementationClass::Tick()
  94. {
  95. std::cout << "Tick" << std::endl;
  96. }
  97.  
  98. int main()
  99. {
  100. MyImplementationClass a;
  101. MyAbstractClass *b = dynamic_cast<MyAbstractClass *>(a.Clone());
  102. b->Tick();
  103. Cloneable::ReleaseClone(b);
  104. }
  105.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In member function 'Cloneable* Cloneable::Auto<InheritingClass>::Clone() const [with InheritingClass = MyImplementationClass, Cloneable = Cloneable]':
prog.cpp:101:66:   instantiated from here
prog.cpp:80:5: error: 'MyImplementationClass::MyImplementationClass(const MyImplementationClass&)' is protected
prog.cpp:48:42: error: within this context
stdout
Standard output is empty