fork download
  1. #include <iostream>
  2.  
  3. template<typename T>
  4. struct Cloneable
  5. {
  6. virtual T *Clone() const
  7. {
  8. return new T(*dynamic_cast<const T*>(this));
  9. }
  10. protected:
  11. Cloneable(){}
  12. Cloneable(const Cloneable &){}
  13. virtual Cloneable &operator=(const Cloneable &){ return*this; }
  14. virtual ~Cloneable(){}
  15. };
  16.  
  17. struct A : Cloneable<A>
  18. {
  19. A() : x(1) {}
  20. A(const A &f) : x(f.x) {}
  21. A(int v) : x(v) {}
  22. virtual A &operator=(const A &f)
  23. {
  24. x = f.x;
  25. return*this;
  26. }
  27.  
  28. virtual A *Clone() const = 0;
  29. virtual void Print() const
  30. {
  31. std::cout << "x=" << x << std::endl;
  32. }
  33.  
  34. virtual ~A(){}
  35. private:
  36. int x;
  37. };
  38.  
  39. struct B : A, Cloneable<B>
  40. {
  41. B() : q(2) {}
  42. B(const B &f) : A(f), q(f.q) {}
  43. B(int v) : A(v-1), q(v) {}
  44. virtual B &operator=(const B &f)
  45. {
  46. A::operator=(f);
  47. q = f.q;
  48. return*this;
  49. }
  50. virtual A &operator=(const A &f)
  51. {
  52. A::operator=(f);
  53. const B *b = dynamic_cast<const B*>(&f);
  54. if(b)
  55. {
  56. q = b->q;
  57. }
  58. return*this;
  59. }
  60.  
  61. using Cloneable<B>::Clone;
  62. virtual void Print() const
  63. {
  64. std::cout << "q=" << q << ", ";
  65. A::Print();
  66. }
  67.  
  68. ~B(){}
  69. private:
  70. int q;
  71. };
  72.  
  73. int main()
  74. {
  75. B b1 (7), b2, *b3 (0);
  76. A &a1 (b1), &a2 (b2), *a3 (0);
  77.  
  78. b1.Print();
  79. b2.Print();
  80.  
  81. a1.Print();
  82. a2.Print();
  83.  
  84. b3 = b1.Clone();
  85. b3->Print();
  86. delete b3;
  87.  
  88. a3 = a1.Clone();
  89. a3->Print();
  90. delete a3;
  91.  
  92. b2 = b1;
  93. b2.Print();
  94.  
  95. a3 = new B(9);
  96. a2 = *a3;
  97. a2.Print();
  98. b2.Print();
  99. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In function ‘int main()’:
prog.cpp:75: error: cannot declare variable ‘b1’ to be of abstract type ‘B’
prog.cpp:40: note:   because the following virtual functions are pure within ‘B’:
prog.cpp:28: note: 	virtual A* A::Clone() const
prog.cpp:75: error: cannot declare variable ‘b2’ to be of abstract type ‘B’
prog.cpp:40: note:   since type ‘B’ has pure virtual functions
prog.cpp:95: error: cannot allocate an object of abstract type ‘B’
prog.cpp:40: note:   since type ‘B’ has pure virtual functions
prog.cpp: In member function ‘T* Cloneable<T>::Clone() const [with T = B]’:
prog.cpp:84:   instantiated from here
prog.cpp:8: error: cannot allocate an object of abstract type ‘B’
prog.cpp:40: note:   since type ‘B’ has pure virtual functions
prog.cpp: In member function ‘T* Cloneable<T>::Clone() const [with T = A]’:
prog.cpp:99:   instantiated from here
prog.cpp:8: error: cannot allocate an object of abstract type ‘A’
prog.cpp:18: note:   because the following virtual functions are pure within ‘A’:
prog.cpp:28: note: 	virtual A* A::Clone() const
stdout
Standard output is empty