fork(1) download
  1. #include <iostream>
  2.  
  3. class Fill{};
  4.  
  5. //====================================================================
  6.  
  7. class Node
  8. {
  9. public:
  10. Node(){}
  11. Node(Fill*) { }
  12.  
  13. virtual ~Node() {}
  14. virtual Node * clone() const = 0;
  15.  
  16. virtual void id() { std::cout << "Node\n"; }
  17. };
  18.  
  19. //====================================================================
  20.  
  21. template <typename Base, typename Derived>
  22. class NodeWrap : public Base
  23. {
  24. public:
  25.  
  26. NodeWrap() { }
  27. NodeWrap(Fill * arg1) : Base(arg1) { }
  28.  
  29. virtual Node *clone() const
  30. {
  31. return new Derived(static_cast<Derived const &>(*this));
  32. }
  33. };
  34.  
  35. //====================================================================
  36.  
  37. template <typename Base, typename Derived>
  38. class NodeWrapVirtual : public virtual Base
  39. {
  40. public:
  41.  
  42. NodeWrapVirtual() { }
  43. NodeWrapVirtual(Fill * arg1) : Base(arg1) { }
  44.  
  45. virtual Node *clone() const
  46. {
  47. return new Derived(static_cast<Derived const &>(*this));
  48. }
  49. };
  50.  
  51. //====================================================================
  52.  
  53. class NodeA : public NodeWrap<Node, NodeA>
  54. {
  55. public:
  56. typedef NodeWrap<Node, NodeA> BaseClass;
  57.  
  58. NodeA() { }
  59. NodeA(Fill * f) : BaseClass(f) { }
  60.  
  61. virtual void id() { std::cout << "NodeA\n"; }
  62.  
  63. };
  64.  
  65. //====================================================================
  66.  
  67. class NodeB : public NodeWrapVirtual<Node, NodeB>
  68. {
  69. public:
  70. typedef NodeWrapVirtual<Node, NodeB> BaseClass;
  71.  
  72. NodeB() { }
  73. NodeB(Fill * f) : BaseClass(f) { }
  74.  
  75. virtual void id() { std::cout << "NodeB\n"; }
  76. };
  77.  
  78. //====================================================================
  79.  
  80. class NodeC : public NodeWrapVirtual<Node, NodeC>
  81. {
  82. public:
  83. typedef NodeWrapVirtual<Node, NodeC> BaseClass;
  84.  
  85. using BaseClass::clone;
  86.  
  87. NodeC() { }
  88. NodeC(Fill * f) : BaseClass(f) { }
  89.  
  90. virtual void id() { std::cout << "NodeC\n"; }
  91. };
  92.  
  93. //====================================================================
  94.  
  95. class NodeD : public NodeWrap<NodeB, NodeD>,
  96. public NodeWrap<NodeC, NodeD>
  97. {
  98. public:
  99.  
  100. typedef NodeWrap<NodeB, NodeD> BaseClassB;
  101. typedef NodeWrap<NodeC, NodeD> BaseClassC;
  102.  
  103. NodeD() { }
  104. NodeD(Fill * f) : BaseClassB(f), BaseClassC(f) { }
  105.  
  106. //using BaseClassB::clone; // (1)
  107. virtual NodeD *clone() const { return new NodeD(*this); } // (2)
  108.  
  109. virtual void id() { std::cout << "NodeD\n"; }
  110. };
  111.  
  112. int main()
  113. {
  114. Node * a = new NodeA;
  115. Node * b = new NodeB;
  116. Node * c = new NodeC;
  117. Node * d = new NodeD;
  118.  
  119. a->id();
  120. b->id();
  121. c->id();
  122. d->id();
  123.  
  124. Node * clone = a->clone();
  125. clone->id();
  126. clone = b->clone();
  127. clone->id();
  128. clone = c->clone();
  129. clone->id();
  130. clone = d->clone();
  131. clone->id();
  132. }
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
NodeA
NodeB
NodeC
NodeD
NodeA
NodeB
NodeC
NodeD