TDDD38/726G82 - Advanced programming in C++ Inheritance & Polymorphism Christoffer Holm Department of Computer and informa�on science
1 Inheritance 2 Polymorphism 3 Excep�on Handling 4 Smart Pointers
1 Inheritance 2 Polymorphism 3 Excep�on Handling 4 Smart Pointers
3 / 35 Inheritance Mental Model class Employee { string name{"Christoffer"}; int id{44}; }; class Teacher : public Employee { string course{"TDDD38"}; }; Teacher c{};
3 / 35 Inheritance Mental Model class Employee { string name{"Christoffer"}; name Christoffer int id{44}; }; id 44 class Teacher : public Employee Employee { course string course{"TDDD38"}; TDDD38 }; Teacher Teacher c{};
4 / 35 Inheritance Protected members class Base struct Derived : Base { { public: Derived(int x) Base(int x) : Base{x} { } : x{x} { } int get() { private: return x; // Error! int x; } }; };
4 / 35 Inheritance Protected members class Base struct Derived : Base { { public: Derived(int x) Base(int x) : Base{x} { } : x{x} { } int get() { protected: return x; // OK! int x; } }; };
5 / 35 Inheritance Protected members protected members are: ‚ inaccessible outside the class; ‚ accessible within derived classes; ‚ accessible by friends of the class.
6 / 35 Inheritance Constructors class Base class Derived : public Base { { public: public: Base(int x); Derived(int x, double y); private: private: int x; double y; }; }; Base::Base(int x) Derived::Derived(int x, double y) : x{x} : Base{x}, y{y} { { } }
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; class Derived1 : public Base { double y{2.34}; }; class Derived11 final : public Derived1 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; class Derived1 : public Base { double y{2.34}; }; class Derived11 final : public Derived1 Derived11 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; class Derived1 : public Base { double y{2.34}; }; Derived1 class Derived11 final : public Derived1 Derived11 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; class Derived1 : public Base { Base double y{2.34}; }; Derived1 class Derived11 final : public Derived1 Derived11 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; x 1 class Derived1 : public Base { Base double y{2.34}; }; Derived1 class Derived11 final : public Derived1 Derived11 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; x 1 class Derived1 : public Base { Base y double y{2.34}; 2.34 }; Derived1 class Derived11 final : public Derived1 Derived11 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; x 1 class Derived1 : public Base { Base y double y{2.34}; 2.34 }; Derived1 class Derived11 final z 56 : public Derived1 Derived11 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; x 1 class Derived1 : public Base { Base y double y{2.34}; 2.34 }; Derived1 class Derived11 final z 56 : public Derived1 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; x 1 class Derived1 : public Base { Base y double y{2.34}; 2.34 }; Derived1 class Derived11 final : public Derived1 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; x 1 class Derived1 : public Base { Base y double y{2.34}; 2.34 }; class Derived11 final : public Derived1 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; x 1 class Derived1 : public Base { Base double y{2.34}; }; class Derived11 final : public Derived1 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; x 1 class Derived1 : public Base { double y{2.34}; }; class Derived11 final : public Derived1 { int z{56}; };
7 / 35 Inheritance Ini�aliza�on & Destruc�on class Base { int x{1}; Derived11 obj{}; }; class Derived1 : public Base { double y{2.34}; }; class Derived11 final : public Derived1 { int z{56}; };
8 / 35 Inheritance Ini�aliza�on & Destruc�on An object is ini�alized in the following order: 1. ini�alize base classes (call constructors); 2. ini�alize all data members in declara�on order. An object is destroyed in the following order: 1. destroy all data members in reverse order; 2. destroy base classes in reverse order.
9 / 35 Inheritance Types of Inheritance ‚ public inheritance ‚ protected inheritance ‚ private inheritance
9 / 35 Inheritance Types of Inheritance ‚ public inheritance ‚ class Derived : public Base ‚ All public and protected members of Base are available as public and protected respec�vely in Derived . ‚ protected inheritance ‚ private inheritance
9 / 35 Inheritance Types of Inheritance ‚ public inheritance ‚ protected inheritance ‚ class Derived : protected Base ‚ All public and protected members of Base are available as protected in Derived . ‚ private inheritance
9 / 35 Inheritance Types of Inheritance ‚ public inheritance ‚ protected inheritance ‚ private inheritance ‚ class Derived : private Base ‚ All members of Base are inherited as private and therefore inaccessible from Derived .
10 / 35 Inheritance What will happen? Why? struct Base { ~Base() { cout << "Base" << endl; } }; struct Derived : public Base { ~Derived() { cout << "Derived" << endl; } }; int main() { Derived d{}; }
1 Inheritance 2 Polymorphism 3 Excep�on Handling 4 Smart Pointers
12 / 35 Polymorphism Dynamic dispatch void print1() void print2() { cout << "1" << endl; } { cout << "2" << endl; } struct Base struct Derived : public Base { { Base() = default; // inherit constructors from Base void print() using Base::Base; { // override default constructor foo(); Derived() } : Derived{print2} { } }; protected: int main() using function_t = void (*)(); { Base* bp {new Base{}}; Base(function_t foo) bp->print(); : foo{foo} { } delete bp; private: bp = new Derived{}; function_t foo{print1}; bp->print(); }; }
13 / 35 Polymorphism Easier dynamic dispatch struct Base { virtual void print() { int main() cout << "1" << endl; { } Base* bp {new Base{}}; }; bp->print(); delete bp; struct Derived : public Base { bp = new Derived{}; void print() override bp->print(); { } cout << "2" << endl; } };
14 / 35 Polymorphism What will happen? Why? struct Base { ~Base() { cout << "Base" << endl; } }; struct Derived : public Base { ~Derived() { cout << "Derived" << endl; } }; int main() { Base* bp{new Derived()}; delete bp; }
14 / 35 Polymorphism What will happen? Why? struct Base { virtual ~Base() { cout << "Base" << endl; } }; struct Derived : public Base { ~Derived() { cout << "Derived" << endl; } }; int main() { Base* bp{new Derived()}; delete bp; }
15 / 35 Polymorphism Virtual destructor ‚ bp is of type Base* (the sta�c type of bp ); ‚ dele�ng bp will call the destructor of Base regardless of what the dynamic type of bp is; ‚ However, if the destructor of base is virtual the compiler will use dynamic dispatch to call the overriden destructor from Derived , which in turn will call the Base destructor. Therefore we should always declare destructors as virtual for types which will be used through pointers.
16 / 35 Polymorphism Virtual Table struct Base void Base::fun() { { virtual ~Base(); cout << val1 << ' ' << val2; virtual void fun(); } int val1{1}; int val2{2}; void Derived1::fun() }; { struct Derived1 : public Base Base::fun(); { cout << ' ' << d; void fun() override; } double d{3.4}; }; void Derived11::fun() struct Derived11 : public Derived1 { { cout << "Derived11 "; void fun() final; Derived1::fun(); }; }
d 3.4 Derived1 Derived11 17 / 35 Polymorphism Virtual Table Base* bp{new Base{}}; vtable for Base vptr +dtor: Base::~Base +fun: Base::fun val1 1 bp vtable for Derived1 Base * val2 2 +dtor: Derived1::~Derived1 +fun: Derived1::fun Base vtable for Derived11 +dtor: Derived11::~Derived11 +fun: Derived11::fun
Recommend
More recommend