Contents
Multiple Inheritance
We can have a class derive from 2 classes.File: multi1.cpp
#include <iostream> using namespace std ; // Base class class BaseA { public: void myFunctionBaseA() { cout << "Some content in parent class BaseA." << endl ; } }; // Another base class class BaseB { public: void myFunctionBaseB() { cout << "Some content in parent class BaseB.." << endl ; } }; // Derived class class MyChildClass: public BaseA, public BaseB { }; int main() { MyChildClass myObj; myObj.myFunctionBaseA() ; myObj.myFunctionBaseB() ; return 0; } Output: $ rm a.exe ; g++ multi1.cpp ; ./a.exe Some content in parent class BaseA. Some content in parent class BaseB..The diamond problem:
class A
class B class C
class D
class D inherits 2 copies of class A
File: multi2.cpp
#include<iostream> using namespace std; //The diamond problem class Person { // Data members of person public: Person(int x) { cout << "Person::Person(int ) called" << endl; } }; class Faculty : public Person { // data members of Faculty public: Faculty(int x):Person(x) { cout<<"Faculty::Faculty(int ) called"<< endl; } }; class Student : public Person { // data members of Student public: Student(int x):Person(x) { cout<<"Student::Student(int ) called"<< endl; } }; class TA : public Faculty, public Student { public: TA(int x):Student(x), Faculty(x) { cout<<"TA::TA(int ) called"<< endl; } }; int main() { TA ta1(30); } $ rm a.exe ; g++ multi2.cpp ; ./a.exe Person::Person(int ) called Faculty::Faculty(int ) called Person::Person(int ) called Student::Student(int ) called TA::TA(int ) called We can see that the constructor for Person gets called twice.Use the "virtual" on class to prevent 2 copies.
File: multi3.cpp
#include<iostream> using namespace std; //Default constructor called for multiple //inheritance with virtual keyword. class Person { public: Person(int x) { cout << "Person::Person(int ) called" << endl; } Person() { cout << "Person::Person() called" << endl; } }; class Faculty : virtual public Person { public: Faculty(int x):Person(x) { cout<<"Faculty::Faculty(int ) called"<< endl; } }; class Student : virtual public Person { public: Student(int x):Person(x) { cout<<"Student::Student(int ) called"<< endl; } }; class TA : public Faculty, public Student { public: TA(int x):Student(x), Faculty(x) { cout<<"TA::TA(int ) called"<< endl; } }; int main() { TA ta1(30); } $ rm a.exe ; g++ multi3.cpp ; ./a.exe Person::Person() called Faculty::Faculty(int ) called Student::Student(int ) called TA::TA(int ) called We notice that the default base class constructor got called instead of the the one with the argument. What if we didn't have a default base class constructor ? Then we get a compiler error of the form: multi3.cpp: In constructor ‘TA::TA(int)’: multi3.cpp:29:40: error: no matching function for call to ‘Person::Person()’ 29 | TA(int x):Student(x), Faculty(x) { |Calling the base class constructor when it has an argument.
File: multi4.cpp
#include<iostream> using namespace std; //Calling the base class constructor with argument class Person { public: Person(int x) { cout << "Person::Person(int ) called" << endl; } Person() { cout << "Person::Person() called" << endl; } }; class Faculty : virtual public Person { public: Faculty(int x):Person(x) { cout<<"Faculty::Faculty(int ) called"<< endl; } }; class Student : virtual public Person { public: Student(int x):Person(x) { cout<<"Student::Student(int ) called"<< endl; } }; class TA : public Faculty, public Student { public: TA(int x):Student(x), Faculty(x), Person(x) { cout<<"TA::TA(int ) called"<< endl; } }; int main() { TA ta1(30); } Output: $ rm a.exe ; g++ multi4.cpp ; ./a.exe rm: cannot remove 'a.exe': No such file or directory Person::Person(int ) called Faculty::Faculty(int ) called Student::Student(int ) called TA::TA(int ) called We need to make the change in the constructor for the bottom most class which is "TA" in this case. TA(int x):Student(x), Faculty(x), Person(x)The above only works for virtual derived classes. We are not referring to a virtual function here but when the virtual keyword in defining the class.
File: multi5.cpp
#include<iostream> using namespace std; //Calling the base class constructor with argument //will not compile for non virtual cases class Person { public: Person(int x) { cout << "Person::Person(int ) called" << endl; } Person() { cout << "Person::Person() called" << endl; } }; class Faculty : public Person { public: Faculty(int x):Person(x) { cout<<"Faculty::Faculty(int ) called"<< endl; } }; class Student : public Person { public: Student(int x):Person(x) { cout<<"Student::Student(int ) called"<< endl; } }; class TA : public Faculty, public Student { public: TA(int x):Student(x), Faculty(x), Person(x) { cout<<"TA::TA(int ) called"<< endl; } }; int main() { TA ta1(30); } $ rm a.exe ; g++ multi5.cpp ; ./a.exe multi5.cpp: In constructor ‘TA::TA(int)’: multi5.cpp:29:43: error: type ‘Person’ is not a direct base of ‘TA’ 29 | TA(int x):Student(x), Faculty(x), Person(x) { | ^~~~~~ bash: ./a.exe: No such file or directory