Review of Inheritance
2 Several Levels of Inheritance Base Class B Derived class D Derived class D1
3 Type Conversions Base Class B Derived class D Derived class D1 D d; //is also of type B D1 d1; //is also of type D, B B b; //is not of type D or D1
4 Assignment b = d Base Class B Derived class D Derived class D1 D d; //is also of type B D1 d1; //is also of type D, B
5 Assignment d = b Base Class B Derived class D Derived class D1 D d; //is also of type B D1 d1; //is also of type D, B B b; //is not of type D
6 Function calls Base Class B Derived class D Derived class D1 D d; //is also of type B void print() {Base::print();} void print() {cout << “B”}
7 Function calls Base Class B Derived class D Derived class D1 D d; //is also of type B D1 d1; //is also of type D, B B b; //is not of type D void print() {Base::print();} void print() {D::print();}
8 Use of Virtual (Dynamic Binding) To enable programming with pointers to different object types The compiler generates code to: inspect the type of the object the pointer points to at run- time and then call the appropriate function D * D1
9 Use of Virtual (Dynamic Binding) D *ptr = new D1(); ptr f(); //dynamic binding – calls f from D1 For dynamic binding to occur for function f: - must use pointers or references - f must exist in D - f must be declared virtual in D
10 Use of Virtual (Dynamic Binding) D d; d.f(); //static binding – calls f from D For dynamic binding to occur for function f: - must use pointers or references - f must exist in D - f must be declared virtual in D
11 Use of Virtual (Dynamic Binding) D *ptr = new D1(); ptr print(); //dynamic binding – calls print from D1 For dynamic binding to occur for function print: - must use pointers or references - print must exist in D (could be implemented or pure virtual) - print must be declared virtual in D
12 Use of Virtual (Dynamic Binding) D *ptr = new D1(); ptr print(); //dynamic binding – calls print from D1 Make sure you go through the steps: 1. Find type of ptr (D* here) 2. Look in that class (D here) for the function (print) 3. If print - is not there (neither declared in D nor inherited from B) compiler error ! - is there and is virtual (either declared virtual explicitly or inherited from B) dynamic binding (print from D1) - is there and not virtual static binding (print from D)
13 Inheritance with Virtual Functions Base Class B virtual void print(){cout <<“B”} Derived class D Derived class D1 not overriden void print(){cout <<“D1”;} which print() is called? D *ptr = new D1; ptr->print(); “D1” Dynamic binding
14 Inheritance with Virtual Functions Base Class B virtual void print(){cout <<“B”} Derived class D Derived class D1 not overriden which one is it then ? D *ptr = new D1; ptr->print(); “B” the one closest in the hierarchy not overriden Dynamic binding occurs but print is not overriden in D1, it is inherited as is from B
15 Inheritance with Virtual Functions Base Class B void print(){cout <<“B”} Derived class D Derived class D1 void print() {cout << “D”} overridden which one is it? D *ptr = new D1; ptr->print(); -- “D” the one closest in the hierarchy Dynamic binding occurs but print is not overridden in D1
16 Virtual Destructors ! Base Class B ~B(); Derived class D Derived class D1 ~D(); which destructor is called ? D *ptr = new D1; Delete ptr; ~D1();
17 Virtual Destructors ! Base Class B ~B(); Derived class D Derived class D1 ~D(); which destructor is called ? D *ptr = new D1; Delete ptr; //~D and ~B called ~D1(); Static binding occurs, because ~D is not virtual
18 Virtual Destructors ! Base Class B ~B(); Derived class D Derived class D1 virtual ~D(); which destructor is called ? D *ptr = new D1; Delete ptr; //~D1, ~D and ~B ~D1(); Dynamic binding occurs, because ~D is virtual
19 Virtual Destructors ! Base Class B virtual ~B(); Derived class D Derived class D1 ~D(); which destructor is called ? D *ptr = new D1; Delete ptr; //~D1, ~D and ~B ~D1();