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. static void ReleaseClone(Cloneable *&clone)
  15. {
  16. clone->ReleaseClone(), clone = /*nullptr*/0;
  17. }
  18. protected:
  19. virtual void ReleaseClone() = 0;
  20. public:
  21. // struct CloningException : public virtual Exception
  22. // {
  23. // CloningException(){}
  24. // CloningException(const char *msg) : Exception(msg) {}
  25. // CloningException(const CloningException &) = delete;
  26. // CloningException &operator=(const CloningException &) = delete;
  27. // virtual ~CloningException(){}
  28. // };
  29.  
  30. template<typename InheritingClass>
  31. struct Auto : public virtual Cloneable
  32. {
  33. typedef InheritingClass ICT;
  34. virtual ICT *Clone() const
  35. {
  36. const ICT *t = dynamic_cast<const ICT *>(this);
  37. if(!t)
  38. {
  39. // throw CloningException();
  40. }
  41. return new ICT(*t);
  42. }
  43. protected:
  44. virtual void ReleaseClone()
  45. {
  46. if(!dynamic_cast<const ICT *>(this))
  47. {
  48. // throw CloningException();
  49. }
  50. delete this;
  51. }
  52. public:
  53. virtual ~Auto(){}
  54. };
  55. };
  56.  
  57. struct MyAbstractClass : public virtual Cloneable
  58. {
  59. MyAbstractClass(){}
  60. protected:
  61. MyAbstractClass(const MyAbstractClass &){}
  62. public:
  63. virtual ~MyAbstractClass(){}
  64.  
  65. MyAbstractClass &operator=(const MyAbstractClass &) = delete;
  66.  
  67. virtual void Tick() = 0;
  68. };
  69.  
  70. struct MyImplementationClass : public virtual MyAbstractClass, public virtual Cloneable::Auto<MyImplementationClass>
  71. {
  72. MyImplementationClass(){}
  73. protected:
  74. MyImplementationClass(const MyImplementationClass &){}
  75. public:
  76. virtual ~MyImplementationClass(){}
  77.  
  78. MyImplementationClass &operator=(const MyImplementationClass &) = delete;
  79.  
  80. virtual void Tick();
  81.  
  82. using Cloneable::Auto<MyImplementationClass>::Clone;
  83. protected:
  84. using Cloneable::Auto<MyImplementationClass>::ReleaseClone;
  85. };
  86.  
  87. void MyImplementationClass::Tick()
  88. {
  89. std::cout << "Tick" << std::endl;
  90. }
  91.  
  92. int main()
  93. {
  94. MyImplementationClass a;
  95. MyAbstractClass *b = a.Clone();
  96. b->Tick();
  97. Cloneable::ReleaseClone(b);
  98. }
  99.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:32:3: error: invalid use of incomplete type 'struct Cloneable'
prog.cpp:4:2: error: forward declaration of 'struct Cloneable'
prog.cpp: In function 'int main()':
prog.cpp:94:27: error: cannot declare variable 'a' to be of abstract type 'MyImplementationClass'
prog.cpp:71:1: note:   because the following virtual functions are pure within 'MyImplementationClass':
prog.cpp:13:22: note: 	virtual Cloneable* Cloneable::Clone() const
prog.cpp:19:16: note: 	virtual void Cloneable::ReleaseClone()
prog.cpp:97:30: error: no matching function for call to 'Cloneable::ReleaseClone(MyAbstractClass*&)'
prog.cpp:14:15: note: candidates are: static void Cloneable::ReleaseClone(Cloneable*&)
prog.cpp:19:16: note:                 virtual void Cloneable::ReleaseClone()
prog.cpp: In member function 'ICT* Cloneable::Auto<InheritingClass>::Clone() const [with InheritingClass = MyImplementationClass, ICT = MyImplementationClass]':
prog.cpp:95:34:   instantiated from here
prog.cpp:41:22: error: cannot allocate an object of abstract type 'MyImplementationClass'
prog.cpp:71:1: note:   since type 'MyImplementationClass' has pure virtual functions
stdout
Standard output is empty