fork(1) download
  1. //If you are not sure what some lines of code do, try looking back at
  2. //previous example programs, notes, or ask a question.
  3.  
  4. #include <iostream>
  5.  
  6. using namespace std;
  7.  
  8. // A diamond inheritance pattern is demonstrated here using virtual inheritance
  9. // All the functions are implemented in the class definitions for conciseness
  10.  
  11. // our base class
  12. class animal {
  13. public:
  14. animal() {cout << "animal constructor" << endl;};
  15. // You're usually going to want to make your destructor virtual so the specific one will be called before the general one
  16. virtual ~animal() {cout << "animal destructor" << endl;};
  17.  
  18. // Speak is pure virtual so "animal" is an abstract class
  19. virtual void speak() const = 0;
  20.  
  21. protected:
  22. // other data
  23. };
  24.  
  25. // specific type of "animal," inherited
  26. class mammal : public virtual animal {
  27. public:
  28. mammal() {cout << "mammal constructor" << endl;};
  29. // the destructor here is also virtual, as this will be a base class
  30. virtual ~mammal() {cout << "mammal destructor" << endl;};
  31.  
  32. // we do not implement "speak", so "mammal" is also abstract
  33.  
  34. protected:
  35. // other data
  36. };
  37.  
  38. // specific type of "animal," inherited
  39. class flying : public virtual animal {
  40. public:
  41. flying() {cout << "flying constructor" << endl;};
  42. // the destructor here is also virtual, as this will be a base class
  43. virtual ~flying() {cout << "flying destructor" << endl;};
  44.  
  45. // we do not implement "speak", so "flying" is also abstract
  46.  
  47. protected:
  48. // other data
  49. };
  50.  
  51. // specific class that inherits from both "mammal" and "flying"
  52. class bat: public mammal, public flying {
  53. public:
  54. bat() {cout << "bat constructor" << endl;};
  55. // not virtual, this ends the chain
  56. ~bat() {cout << "bat destructor" << endl;};
  57.  
  58. // here we implement "speak," making bat a non-abstract class
  59. void speak() const {cout << "squeak!" << endl;};
  60.  
  61. private:
  62. // other data
  63. };
  64.  
  65. int main() {
  66. // we can't create any of these, as they are abstract
  67. // animal a;
  68. // mammal m;
  69. // flying f;
  70.  
  71. cout << endl << "constructing bat" << endl << endl;
  72.  
  73. bat b;
  74.  
  75. cout << endl << "calling speak on general animal pointer" << endl << endl;
  76.  
  77. animal* someAnimal = &b;
  78. someAnimal->speak();
  79.  
  80. cout << endl << "calling speak on general mammal pointer" << endl << endl;
  81.  
  82. mammal* someMammal = &b;
  83. someMammal->speak();
  84.  
  85. cout << endl << "calling speak on general flying pointer" << endl << endl;
  86.  
  87. animal* someFlying = &b;
  88. someFlying->speak();
  89.  
  90. cout << endl << "destructing bat" << endl << endl;
  91. return 0;
  92. }
  93.  
Success #stdin #stdout 0s 3460KB
stdin
Standard input is empty
stdout
constructing bat

animal constructor
mammal constructor
flying constructor
bat constructor

calling speak on general animal pointer

squeak!

calling speak on general mammal pointer

squeak!

calling speak on general flying pointer

squeak!

destructing bat

bat destructor
flying destructor
mammal destructor
animal destructor