11 Inheritance PDF
11 Inheritance PDF
11. Inheritance
Guess the
output
class Vehicle { class Automobile : public Vehicle{
int wheels_count; float engine_cc;
protected: protected:
float max_speed; int gear_count;
public: public:
string manufacturer; Automobile(int wheels_count, float max_speed,
Vehicle(int, float, string); string manufacturer, float engine_cc,
void print(bool); int gear_count):
}; engine_cc(engine_cc),
Vehicle::Vehicle(int wheels_count, float max_speed, gear_count(gear_count),
string manufacturer): Vehicle(wheels_count, max_speed, manufacturer) {
wheels_count(wheels_count), cout << "Automobile constructor called\n";
max_speed(max_speed), }
manufacturer(manufacturer){ void print() {
cout << "Vehicle constructor called\n"; cout << max_speed << endl << manufacturer << endl;
} cout << engine_cc << endl << gear_count << endl;
void Vehicle::print(bool in_single_line) { }
if(in_single_line) { };
cout << wheels_count << " " << max_speed;
cout << " " << manufacturer << endl; int main() {
} Automobile automobile(2, 100, "Honda", 125, 4);
else { // error: no matching function for call to
cout << wheels_count << endl << max_speed; // ‘Automobile::print(bool)
cout << endl << manufacturer << endl; automobile.print(true);
} return 0;
} }
Functions/methods can be overloaded within the same scope only
Here Vehicle and Automobile are two differenct classes and hence different scopes
When we define print function in Automobile then all the print functions of the Vehicle class are
inaccessible in Automobile class
class Vehicle { class Automobile : public Vehicle{
int wheels_count; float engine_cc;
protected: protected:
float max_speed; int gear_count;
public: public:
string manufacturer; Automobile(int wheels_count, float max_speed,
Vehicle(int, float, string); string manufacturer, float engine_cc,
void print(bool); int gear_count):
void print(); engine_cc(engine_cc),
}; gear_count(gear_count),
Vehicle::Vehicle(int wheels_count, float max_speed, Vehicle(wheels_count, max_speed, manufacturer) {
string manufacturer): cout << "Automobile constructor called\n";
wheels_count(wheels_count), }
max_speed(max_speed), void print() {
manufacturer(manufacturer){ cout << max_speed << endl << manufacturer << endl;
cout << "Vehicle constructor called\n"; cout << engine_cc << endl << gear_count << endl;
} }
void Vehicle::print(bool in_single_line) { };
if(in_single_line) {
cout << wheels_count << " " << max_speed; int main() {
cout << " " << manufacturer << endl; Automobile automobile(2, 100, "Honda", 125, 4);
} automobile.print();
else { return 0;
cout << wheels_count << endl << max_speed; }
cout << endl << manufacturer << endl;
}
} Vehicle constructor called
void Vehicle::print() { Automobile constructor
cout << "Wheel Count: " << wheels_count << endl;
cout << "Max Speed: " << max_speed << endl; called
cout << "Manufacturer: " << manufacturer << endl; 100
} Honda
125
class Vehicle { class Automobile : public Vehicle{
int wheels_count; float engine_cc;
protected: protected:
float max_speed; int gear_count;
public: public:
string manufacturer; Automobile(int wheels_count, float max_speed,
Vehicle(int, float, string); string manufacturer, float engine_cc,
void print(bool); int gear_count):
void print(); engine_cc(engine_cc),
}; gear_count(gear_count),
Vehicle::Vehicle(int wheels_count, float max_speed, Vehicle(wheels_count, max_speed, manufacturer) {
string manufacturer): cout << "Automobile constructor called\n";
wheels_count(wheels_count), }
max_speed(max_speed), void print(bool in_single_line) {
manufacturer(manufacturer){ if(in_single_line) {
cout << "Vehicle constructor called\n"; cout << max_speed << " " << manufacturer;
} cout << " " << engine_cc << " " << gear_count;
void Vehicle::print(bool in_single_line) { cout << endl;
if(in_single_line) { }
cout << wheels_count << " " << max_speed; else {
cout << " " << manufacturer << endl; cout << max_speed << endl << manufacturer;
} cout << endl << engine_cc <<endl << gear_count;
else { cout << endl;
cout << wheels_count << endl << max_speed; }
cout << endl << manufacturer << endl;
} }
} };
void Vehicle::print() { int main() {
cout << "Wheel Count: " << wheels_count << endl; Automobile automobile(2, 100, "Honda", 125, 4);
cout << "Max Speed: " << max_speed << endl; automobile.print(true);
cout << "Manufacturer: " << manufacturer << endl; return 0; Vehicle constructor called
} } Automobile constructor called
100 Honda 125 4
class Vehicle { class Automobile : public Vehicle{ int main() {
int wheels_count; float engine_cc; Automobile automobile(2, 100, "Honda", 125, 4);
protected: float wheels_count = 16; automobile.print(true);
float max_speed; protected: return 0;
public: int gear_count; }
string manufacturer; int max_speed = 1236; // supersonic
Vehicle(int, float, string); public:
void print(bool); string manufacturer = "Magic Corp.";
void print(); Automobile(int wheels_count, float max_speed,
}; string manufacturer, float engine_cc,
Vehicle::Vehicle(int wheels_count, float max_speed, int gear_count):
string manufacturer): engine_cc(engine_cc),
wheels_count(wheels_count), gear_count(gear_count),
max_speed(max_speed), Vehicle(wheels_count, max_speed, manufacturer) {
manufacturer(manufacturer){ cout << "Automobile constructor called\n";
cout << "Vehicle constructor called\n"; }
} void print(bool in_single_line) {
void Vehicle::print(bool in_single_line) { if(in_single_line) {
if(in_single_line) { cout << wheels_count << " ";
cout << wheels_count << " " << max_speed; cout << max_speed << " " << manufacturer;
cout << " " << manufacturer << endl; cout << " " << engine_cc << " " << gear_count;
} cout << endl;
else { }
cout << wheels_count << endl << max_speed; else {
cout << endl << manufacturer << endl; cout << wheels_count << endl;
} cout << max_speed << endl << manufacturer;
} cout << endl << engine_cc <<endl << gear_count;
void Vehicle::print() { cout << endl;
cout << "Wheel Count: " << wheels_count << endl; }
cout << "Max Speed: " << max_speed << endl;
cout << "Manufacturer: " << manufacturer << endl; } Vehicle constructor called
} }; Automobile constructor called
16 1236 Magic Corp. 125 4
class Vehicle { class Automobile : public Vehicle{ int main() {
int wheels_count; float engine_cc; Automobile automobile(2, 100, "Honda", 125, 4);
protected: float wheels_count = 16; automobile.print(true);
float max_speed; protected: cout << automobile.manufacturer << endl;
public: int gear_count; cout << automobile.Vehicle::manufacturer << endl;
string manufacturer; int max_speed = 1236; return 0;
Vehicle(int, float, string); public: }
void print(bool); string manufacturer = "Magic Corp.";
void print(); Automobile(int wheels_count, float max_speed,
}; string manufacturer, float engine_cc,
Vehicle::Vehicle(int wheels_count, float max_speed, int gear_count):
string manufacturer): engine_cc(engine_cc),
wheels_count(wheels_count), gear_count(gear_count),
max_speed(max_speed), Vehicle(wheels_count, max_speed, manufacturer) {
manufacturer(manufacturer){ cout << "Automobile constructor called\n";
cout << "Vehicle constructor called\n"; }
} void print(bool in_single_line) {
void Vehicle::print(bool in_single_line) { if(in_single_line) {
if(in_single_line) { // error:‘int Vehicle::wheels_count’ is private
cout << wheels_count << " " << max_speed; // cout << Vehicle::wheels_count << " "; Vehicle constructor called
cout << " " << manufacturer << endl; cout << Vehicle::max_speed << " "; Automobile constructor called
} cout << Vehicle::manufacturer; 100 Honda 125 4
else { cout << " " << engine_cc << " " << gear_count;
cout << wheels_count << endl << max_speed; cout << endl; Magic Corp.
cout << endl << manufacturer << endl; } else { Honda
} // error:‘int Vehicle::wheels_count’ is private
} // cout << Vehicle::wheels_count << endl;
void Vehicle::print() { cout << Vehicle::max_speed << endl;
cout << "Wheel Count: " << wheels_count << endl; cout << Vehicle::manufacturer;
cout << "Max Speed: " << max_speed << endl; cout << endl << engine_cc << endl << gear_count;
cout << "Manufacturer: " << manufacturer << endl; cout << endl;
} }
}
};
class Vehicle { class Automobile : public Vehicle{
int wheels_count; float engine_cc;
protected: protected:
float max_speed; int gear_count;
public: public:
string manufacturer; Automobile(int wheels_count, float max_speed,
Vehicle(int, float, string); string manufacturer, float engine_cc,
void print(bool); int gear_count):
}; engine_cc(engine_cc),
Vehicle::Vehicle(int wheels_count, float max_speed, gear_count(gear_count),
string manufacturer): Vehicle(wheels_count, max_speed, manufacturer) {
wheels_count(wheels_count), cout << "Automobile constructor called\n";
max_speed(max_speed), }
manufacturer(manufacturer){ void print() {
cout << "Vehicle constructor called\n"; Vehicle::print(false);
} cout << engine_cc << endl << gear_count << endl;
void Vehicle::print(bool in_single_line) { }
if(in_single_line) { };
cout << wheels_count << " " << max_speed;
cout << " " << manufacturer << endl; int main() {
} Automobile automobile(2, 100, "Honda", 125, 4);
else { // error: no matching function for call to
cout << wheels_count << endl << max_speed; // ‘Automobile::print(bool)
cout << endl << manufacturer << endl; // automobile.print(true);
} automobile.Vehicle::print(true); Vehicle constructor called
} automobile.print(); Automobile constructor called
return 0;
2 100 Honda
}
2
100
Honda
125
4
Inheritance
Constructors, destructor, friend functions, friend classes, and static members
of base class are not inherited by derived class.
Friend fuctions and classes have access to protected members of the class
along with private and public members of the class
class Vehicle { class Automobile : public Vehicle{ void friend_fun1() {
int wheels_count; float engine_cc; cout << "friend_fun1 called\n";
protected: protected: Automobile automobile(2, 100, "Honda", 125, 4);
float max_speed; int gear_count; cout << automobile.wheels_count << endl;
public: public: cout << automobile.max_speed << endl;
string manufacturer; friend void friend_fun2(); cout << automobile.manufacturer << endl;
Vehicle(int, float, string); Automobile(int wheels_count, float max_speed, // error: 'float Automobile::engine_cc' is private
void print(bool); string manufacturer, float engine_cc, // cout << automobile.engine_cc << endl;
friend void friend_fun1(); int gear_count): // error: 'int Automobile::gear_count' is protected
}; engine_cc(engine_cc), // cout << automobile.gear_count << endl;
Vehicle::Vehicle(int wheels_count, float max_speed, gear_count(gear_count), }
string manufacturer): Vehicle(wheels_count, max_speed, manufacturer) {
wheels_count(wheels_count), cout << "Automobile constructor called\n"; void friend_fun2() {
max_speed(max_speed), } cout << "friend_fun2 called\n";
manufacturer(manufacturer){ void print() { Automobile automobile(2, 100, "Honda", 125, 4);
cout << "Vehicle constructor called\n"; Vehicle::print(false); // error: 'int Vehicle::wheels_count' is private
} cout << engine_cc << endl << gear_count << endl; // cout << automobile.wheels_count << endl;
void Vehicle::print(bool in_single_line) { } cout << automobile.max_speed << endl;
if(in_single_line) { }; cout << automobile.manufacturer << endl;
cout << wheels_count << " " << max_speed; cout << automobile.engine_cc << endl;
cout << " " << manufacturer << endl;
}
friend_fun1 called cout << automobile.gear_count << endl;
}
else { Vehicle constructor called
cout << wheels_count << endl << max_speed;
cout << endl << manufacturer << endl;
Automobile constructor called int main() {
friend_fun1();
} 2 friend_fun2();
}
100 return 0;
}
Honda
friend_fun2 called
Vehicle constructor called
Automobile constructor called
100
Honda
125
4
class Vehicle { class Engine { class Automobile : public Vehicle{
int wheels_count; int cylinders_count; Engine e;
protected: protected: protected:
float max_speed; string cylinders_arrangement; //v-type, inline etc... int gear_count;
public: public: public:
string manufacturer; float engine_cc; Automobile(int wheels_count, float max_speed,
Vehicle(int, float, string); Engine(int cylinders_count, string manufacturer, int cylinders_count,
void vehicle_print(); string cylinders_arrangement, float engine_cc): string cylinders_arrangement, float engine_cc,
~Vehicle() { cylinders_count(cylinders_count), int gear_count):
cout << "Vehicle Destructor called\n"; cylinders_arrangement(cylinders_arrangement), gear_count(gear_count),
} engine_cc(engine_cc){ e(cylinders_count, cylinders_arrangement,
}; cout << "Engine constructor called\n"; engine_cc),
Vehicle::Vehicle(int wheels_count, float max_speed, } Vehicle(wheels_count, max_speed, manufacturer) {
string manufacturer): ~Engine() { cout << "Automobile constructor called\n";
wheels_count(wheels_count), cout << "Engine Destructor called\n"; }
max_speed(max_speed), } ~Automobile() {
manufacturer(manufacturer){ void print() { cout << "Automobile Destructor called\n";
cout << "Vehicle constructor called\n"; cout << "cyl cnt: " << cylinders_count << endl; }
} cout << "cyl arr: " << cylinders_arrangement; void print() {
void Vehicle::vehicle_print() { cout << endl << "eng cc: " << engine_cc << endl; vehicle_print();
cout << "Wheel Count: " << wheels_count << endl; } e.print();
cout << "Max Speed: " << max_speed << endl; }; cout << "Gear Count: " << gear_count << endl;
cout << "Manufacturer: " << manufacturer << endl; }
} };
class B {
protected:
int num2 = 2;
};
int main() {
C c;
c.print();
return 0;
}
123
class A { class C: public A, public B {
protected: protected:
int num1 = 1; int num3 = 3;
public: public:
A() { C() {
cout << "A constructor called\n"; cout << "C constructor called\n";
} }
~A() { ~C() {
cout << "A destructor called\n"; cout << "C destructor called\n";
} }
}; void print() {
cout << num1 << num2 << num3 << endl;
class B { }
protected: };
int num2 = 2;
public: int main() {
B() { C c;
cout << "B constructor called\n"; c.print();
} return 0; A constructor called
~B() { } B constructor called
cout << "B destructor called\n"; C constructor called
} 123
}; C destructor called
B destructor called
A destructor called
class A { class C: public B, public A {
protected: protected:
int num1; int num3 = 3;
public: public:
A(int n): num1(n) { B b;
cout << "A constructor called\n"; C(int num1, int num2, int num3, int num4):
} A(num2),
~A() { B(num1),
cout << "A destructor called\n"; num3(num3),
} b(num4) {
}; cout << "C constructor called\n";
}
class B { ~C() {
protected: cout << "C destructor called\n";
int num2 = 2; }
public: void print() {
B(int n): num2(n) { cout << num1 << num2 << num3;
cout << "B constructor called\n"; } B constructor called
} }; A constructor called
~B() { B constructor called
cout << "B destructor called\n"; int main() { C constructor called
} C c(1, 3, 2, 4); 3124
void print() { c.print(); C destructor called
cout << num2 << endl; c.b.print(); B destructor called
} return 0; A destructor called
}; } B destructor called
class A { class C: public B, public A {
protected: protected:
int num1; int num3;
public: public:
A(int n): num1(n) { B b;
cout << "A constructor called\n"; C(int num1, int num2, int num3, int num4):
} A(num2),
~A() { B(num1),
cout << "A destructor called\n"; num3(num3),
} b(num4) {
}; cout << "C constructor called\n";
}
class B { ~C() {
protected: cout << "C destructor called\n";
int num2; }
public: void print() {
B(int n): num2(n) { cout << num1 << num2 << num3;
cout << "B constructor called\n"; } B constructor called
} }; A constructor called
~B() { B constructor called
cout << "B destructor called\n"; int main() { C constructor called
} C c(1, 3, 2, 4); 3124
void print() { c.print(); C destructor called
cout << num2 << endl; c.b.print(); B destructor called
} return 0; A destructor called
}; } B destructor called
class A { class C: public B, public A {
protected: protected:
int num1; int num3 = 1;
int num4;
public:
public:
A(int n): num1(n) { B b;
cout << "A constructor called\n"; C(int n1, int n2, int n3, int n4):
} A(n2), B constructor called
~A() { B(n1),
A constructor called
cout << "A destructor called\n"; num4(num3 * 2),
num3(n3),
B constructor called
} C constructor called
}; b(n4) {
cout << "C constructor called\n"; 31244
} C destructor called
class B { ~C() { B destructor called
protected: cout << "C destructor called\n"; A destructor called
int num2; } B destructor called
public: void print() {
B(int n): num2(n) { cout << num1 << num2 << num3 << num4;
cout << "B constructor called\n"; }
} };
int main() {
~B() {
C c(1, 3, 2, 4);
cout << "B destructor called\n"; c.print();
} c.b.print();
void print() { return 0;
cout << num2 << endl; }
}
};
class A { class C: public B, public A {
protected: protected:
int num1; int num3 = 1;
int num4;
public:
public:
A(int n): num1(n) { B b;
cout << "A constructor called\n"; C(int n1, int n2, int n3, int n4):
} A(n2),
~A() { B(n1),
cout << "A destructor called\n"; num4(num3 * 2),
} num3(n3),
}; b(n4) {
cout << "C constructor called\n";
}
class B { ~C() {
protected: cout << "C destructor called\n";
int num1; }
public: void print() {
B(int n): num1(n) { // error: reference to 'num1' is ambiguous
cout << "B constructor called\n"; cout << num1 << num1 << num3 << num4;
} }
};
~B() {
int main() {
cout << "B destructor called\n"; C c(1, 3, 2, 4);
} c.print();
void print() { c.b.print();
cout << num1 << endl; return 0;
} }
};
class A { class C: public B, public A {
protected: protected:
int num1; int num3 = 1;
int num4;
public:
public:
A(int n): num1(n) { B b;
cout << "A constructor called\n"; C(int n1, int n2, int n3, int n4):
} A(n2), B constructor called
~A() { B(n1),
A constructor called
cout << "A destructor called\n"; num4(num3 * 2),
num3(n3),
B constructor called
} C constructor called
}; b(n4) {
cout << "C constructor called\n"; 31244
} C destructor called
class B { ~C() { B destructor called
protected: cout << "C destructor called\n"; A destructor called
int num1; } B destructor called
public: void print() {
B(int n): num1(n) { cout << A::num1 << B::num1 << num3 << num4;
cout << "B constructor called\n"; }
} };
int main() {
~B() {
C c(1, 3, 2, 4);
cout << "B destructor called\n"; c.print();
} c.b.print();
void print() { return 0;
cout << num1 << endl; }
}
};
class A { class D: public B, public C {
public: public:
int num1 = 1; D(){
A(){
cout << "D constructor called\n";
cout << "A constructor called\n";
} }
~A() { ~D() {
cout << "A destructor called\n"; cout << "D destructor called\n";
} }
}; void print() {
class B: public A { // error: reference to num1 is ambiguous
public: cout << num1 << endl;
B(){
}
cout << "B constructor called\n";
} };
~B() {
cout << "B destructor called\n"; int main() {
} D d;
}; d.C::num1 = 7;
class C: public A { d.print();
public: return 0;
C(){
}
cout << "C constructor called\n";
}
~C() {
cout << "C destructor called\n";
}
};
class A { class D: public B, public C {
public: public:
int num1 = 1; D(){
A(){
cout << "D constructor called\n";
cout << "A constructor called\n";
} }
~A() { ~D() {
cout << "A destructor called\n"; cout << "D destructor called\n";
} }
}; void print() {
class B: public A { // error: 'A' is an ambiguous base of 'D'
public: cout << A::num1 << endl;
B(){
}
cout << "B constructor called\n";
} };
~B() {
cout << "B destructor called\n"; int main() {
} D d;
}; d.C::num1 = 7;
class C: public A { d.print();
public: return 0;
C(){
}
cout << "C constructor called\n";
}
~C() {
cout << "C destructor called\n";
}
};
class A { class D: public B, public C {
public: public:
int num1 = 1; D(){
A(){
cout << "D constructor called\n";
cout << "A constructor called\n";
} }
~A() { ~D() {
cout << "A destructor called\n"; cout << "D destructor called\n";
} }
}; void print() {
class B: public A {
public: cout << B::num1 << " " << C::num1 << endl;
B(){
}
cout << "B constructor called\n";
} };
~B() { A constructor called
cout << "B destructor called\n"; int main() { B constructor called
} D d; A constructor called
}; d.C::num1 = 7; C constructor called
class C: public A { d.print();
public:
D constructor called
return 0; 17
C(){
} D destructor called
cout << "C constructor called\n";
} C destructor called
~C() { A destructor called
cout << "C destructor called\n"; B destructor called
} A destructor called
};
class A { class D: public B, public C {
public: public:
int num1 = 1; D(){
A(){
cout << "D constructor called\n";
cout << "A constructor called\n";
} }
~A() { ~D() {
cout << "A destructor called\n"; cout << "D destructor called\n";
} }
}; void print() {
class B: virtual public A {
public: cout << B::num1 << " " << C::num1 << endl;
B(){
}
cout << "B constructor called\n";
} };
~B() { A constructor called
cout << "B destructor called\n"; int main() { B constructor called
} D d; C constructor called
}; d.C::num1 = 7; D constructor called
class C: virtual public A { d.print();
public:
77
return 0; D destructor called
C(){
} C destructor called
cout << "C constructor called\n";
} B destructor called
~C() { A destructor called
cout << "C destructor called\n";
}
};
class A { class E {
public: public:
int num1 = 1; E(){ A constructor called
A(){ cout << "E constructor called\n"; E constructor called
cout << "A constructor called\n"; } B constructor called
} ~E() { C constructor called
~A() { cout << "E destructor called\n"; D constructor called
cout << "A destructor called\n"; } 77
} }; D destructor called
}; class D: public E, public B, public C {
C destructor called
class B: virtual public A { public:
public: D(){ B destructor called
B(){ cout << "D constructor called\n"; E destructor called
cout << "B constructor called\n"; } A destructor called
} ~D() {
~B() { cout << "D destructor called\n";
cout << "B destructor called\n"; }
} void print() {
}; cout << B::num1 << " " << C::num1 << endl;
class C: virtual public A { }
public: };
C(){ int main() {
cout << "C constructor called\n"; D d;
} d.C::num1 = 7;
~C() { d.print();
cout << "C destructor called\n"; return 0;
} }
};
Virtual base class is constructed before any other class in multiple inheritance
class A { class E: virtual public A {
public: public:
int num1 = 1; E(){ A constructor called
A(){ cout << "E constructor called\n"; E constructor called
cout << "A constructor called\n"; } A constructor called
} ~E() { B constructor called
~A() { cout << "E destructor called\n"; C constructor called
cout << "A destructor called\n"; } D constructor called
} }; 177
}; class D: public E, public B, public C {
D destructor called
class B: public A { public:
public: D(){ C destructor called
B(){ cout << "D constructor called\n"; B destructor called
cout << "B constructor called\n"; } A destructor called
} ~D() { E destructor called
~B() { cout << "D destructor called\n"; A destructor called
cout << "B destructor called\n"; }
} void print() {
}; cout << B::num1 << " " << C::num1;
class C: virtual public A { cout << " " << E::num1 << endl;
public: }
C(){ };
cout << "C constructor called\n"; int main() {
} D d;
~C() { d.C::num1 = 7;
cout << "C destructor called\n"; d.print();
} return 0;
}; }
Virtual base class is constructed before any other class in multiple inheritance
Interesting reads
Accessing protected members in a derived class trhough object of base
class is not permitted
https://stackoverflow.com/questions/3247671/accessing-protected-
members-in-a-derived-class
Inheritance of constructors and destructor
https://stackoverflow.com/questions/14184341/c-constructor-destructor-
inheritance