tdde18 & 726g77 - inheritance & polymorphism

154
TDDE18 & 726G77 Inheritance & Polymorphism Christoffer Holm Department of Computer and informaon science

Upload: others

Post on 07-Dec-2021

10 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: TDDE18 & 726G77 - Inheritance & Polymorphism

TDDE18 & 726G77Inheritance & Polymorphism

Christoffer Holm

Department of Computer and information science

Page 2: TDDE18 & 726G77 - Inheritance & Polymorphism

1 std::vector2 Inheritance3 Polymorphism4 More on Polymorphism5 Type information6 Exceptions7 Command‐line argument

Page 3: TDDE18 & 726G77 - Inheritance & Polymorphism

1 std::vector2 Inheritance3 Polymorphism4 More on Polymorphism5 Type information6 Exceptions7 Command‐line argument

Page 4: TDDE18 & 726G77 - Inheritance & Polymorphism

3 / 64

std::vectorStorage

‚ Linked storage

‚ Sequential Storage

Page 5: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

std::vector<int> v {5, 3, 1, 2};

Page 6: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

std::vector<int> v {5, 3, 1, 2};

5 3 1 2[0] [1] [2] [3]

Page 7: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

v.at(1) = 4;

5 3 1 2[0] [1] [2] [3]

Page 8: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

v.at(1) = 4;

5 4 1 2[0] [1] [2] [3]

Page 9: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

v.push_back(3);

5 4 1 2[0] [1] [2] [3]

Page 10: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

v.push_back(3);

5 4 1 2 3[0] [1] [2] [3] [4]

Page 11: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

v.back() = 6;

5 4 1 2 3[0] [1] [2] [3] [4]

Page 12: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

v.back() = 6;

5 4 1 2 6[0] [1] [2] [3] [4]

Page 13: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

v.pop_back();

5 4 1 2 6[0] [1] [2] [3] [4]

Page 14: TDDE18 & 726G77 - Inheritance & Polymorphism

4 / 64

std::vectorSequential Storage

v.pop_back();

5 4 1 2[0] [1] [2] [3]

Page 15: TDDE18 & 726G77 - Inheritance & Polymorphism

5 / 64

std::vectorLooping through

vector<string> words {...};for (int i{0}; i < words.size(); ++i){cout << words.at(i) << endl;

}

Page 16: TDDE18 & 726G77 - Inheritance & Polymorphism

5 / 64

std::vectorLooping through

vector<string> words {...};for (string word : words){cout << word << endl;

}

Page 17: TDDE18 & 726G77 - Inheritance & Polymorphism

5 / 64

std::vectorLooping through

vector<string> words {...};for (string const& word : words){cout << word << endl;

}

Page 18: TDDE18 & 726G77 - Inheritance & Polymorphism

6 / 64

std::vectorExample

#include <vector>#include <iostream>using namespace std;int main(){vector<int> values{};int value{};

// read values until ctrl+Dwhile (cin >> value){values.push_back(value);

}

// double each valuefor (int& e : values){e = 2*e;

}}

Page 19: TDDE18 & 726G77 - Inheritance & Polymorphism

1 std::vector2 Inheritance3 Polymorphism4 More on Polymorphism5 Type information6 Exceptions7 Command‐line argument

Page 20: TDDE18 & 726G77 - Inheritance & Polymorphism

8 / 64

Inheritanceclass Rectangle{public:

Rectangle(double w, double h): width{w}, height{h} { }

double area() const{return height * width;

}double get_height() const{return height;

}double get_width() const{return width;

}private:

double width;double height;

};

class Triangle{public:Triangle(double w, double h): width{w}, height{h} { }

double area() const{return height * width / 2;

}double get_height() const{return height;

}double get_width() const{return width;

}private:double width;double height;

};

Page 21: TDDE18 & 726G77 - Inheritance & Polymorphism

9 / 64

InheritanceWhat is inheritance?

width

height

get_width()

get_height()

area()

Rectangle

width

height

get_width()

get_height()

area()

Triangle

Page 22: TDDE18 & 726G77 - Inheritance & Polymorphism

9 / 64

InheritanceWhat is inheritance?

width

height

get_width()

get_height()

area()

Rectangle

width

height

get_width()

get_height()

area()

Triangle

common

Page 23: TDDE18 & 726G77 - Inheritance & Polymorphism

9 / 64

InheritanceWhat is inheritance?

width

height

get_width()

get_height()

Shape

area()

Rectangle

width

height

get_width()

get_height()

Shape

area()

Triangle

Page 24: TDDE18 & 726G77 - Inheritance & Polymorphism

10 / 64

Inheritance// common codeclass Shape{public:

Shape(double w, double h): width{w}, height{h} { }

double get_height() const{return height;

}

double get_width() const{return width;

}

private:

double width;double height;

};

Page 25: TDDE18 & 726G77 - Inheritance & Polymorphism

10 / 64

Inheritance// common codeclass Shape{public:

Shape(double w, double h): width{w}, height{h} { }

double get_height() const{return height;

}

double get_width() const{return width;

}

private:

double width;double height;

};

class Rectangle : public Shape{public:Rectangle(double w, double h): width{w}, height{h} { }

double area() const{return width * height;

}};

class Triangle : public Shape{public:Triangle(double w, double h): width{w}, height{h} { }

double area() const{return width * height / 2;

}};

Page 26: TDDE18 & 726G77 - Inheritance & Polymorphism

11 / 64

Inheritance

Shape.cc: In constructor ‘Rectangle::Rectangle(double, double)’:Shape.cc: error: ‘double Shape::width’ is private within this context

: width{w}, height{h} { }^~~~~

Shape.cc: note: declared private heredouble width;

^~~~~Shape.cc: error: ‘double Shape::height’ is private within this context

: width{w}, height{h} { }^~~~~~

Shape.cc: note: declared private heredouble height;

^~~~~~

Page 27: TDDE18 & 726G77 - Inheritance & Polymorphism

12 / 64

Inheritance// common codeclass Shape{public:

Shape(double w, double h): width{w}, height{h} { }

double get_height() const{return height;

}

double get_width() const{return width;

}

private:

double width;double height;

};

class Rectangle : public Shape{public:Rectangle(double w, double h): Shape{w, h} { }

double area() const{return width * height;

}};

class Triangle : public Shape{public:Triangle(double w, double h): Shape{w, h} { }

double area() const{return width * height / 2;

}};

Page 28: TDDE18 & 726G77 - Inheritance & Polymorphism

13 / 64

Inheritance

Shape.cc: In member function ‘double Rectangle::area() const’:Shape.cc: error: ‘double Shape::width’ is private within this context

return width * height;^~~~~

Shape.cc: note: declared private heredouble width;

^~~~~Shape.cc: error: ‘double Shape::height’ is private within this context

return width * height;^~~~~~

Shape.cc: note: declared private heredouble height;

^~~~~~

Page 29: TDDE18 & 726G77 - Inheritance & Polymorphism

14 / 64

Inheritance// common codeclass Shape{public:

Shape(double w, double h): width{w}, height{h} { }

double get_height() const{return height;

}

double get_width() const{return width;

}

protected:

double width;double height;

};

class Rectangle : public Shape{public:Rectangle(double w, double h): Shape{w, h} { }

double area() const{return width * height;

}};

class Triangle : public Shape{public:Triangle(double w, double h): Shape{w, h} { }

double area() const{return width * height / 2;

}};

Page 30: TDDE18 & 726G77 - Inheritance & Polymorphism

15 / 64

InheritanceData members in derived class

class Named_Rectangle : public Rectangle{public:Named_Rectangle(int width, int height, std::string const& name): Rectangle{width, height}, name{name}

{ }private:std::string name{};

};

Page 31: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

Page 32: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

Named_Rectangle

Page 33: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

Shape

Named_Rectangle

Page 34: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

width 12

Shape

Named_Rectangle

Page 35: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

width 12

height 13

Shape

Named_Rectangle

Page 36: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

width 12

height 13

Shape

name My Rectangle

Named_Rectangle

Page 37: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

width 12

height 13

Shape

Named_Rectangle

Page 38: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

width 12

height 13

Shape

Page 39: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

width 12

Shape

Page 40: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

Shape

Page 41: TDDE18 & 726G77 - Inheritance & Polymorphism

16 / 64

InheritanceInitialization & Destruction

Named_Rectangle r {12, 13, "My Rectangle"};

Page 42: TDDE18 & 726G77 - Inheritance & Polymorphism

17 / 64

InheritanceBinding to references

void print_height(Triangle& triangle){cout << triangle.get_height() << endl;

}

void print_height(Rectangle& triangle){cout << triangle.get_height() << endl;

}

Page 43: TDDE18 & 726G77 - Inheritance & Polymorphism

17 / 64

InheritanceBinding to references

void print_height(Shape& shape){cout << shape.get_height() << endl;

}

Page 44: TDDE18 & 726G77 - Inheritance & Polymorphism

18 / 64

Inheritancearea()

void print_area(Shape& shape){cout << shape.area() << endl;

}

Page 45: TDDE18 & 726G77 - Inheritance & Polymorphism

18 / 64

Inheritancearea()

Shape.cc: In function ‘void print_area(Shape&)’:Shape.cc: error: ‘class Shape’ has no member named ‘area’

cout << shape.area() << endl;^~~~

Page 46: TDDE18 & 726G77 - Inheritance & Polymorphism

19 / 64

InheritanceLet’s add area() to Shape

class Shape{public:

// ...double area() const{return 0;

}// ...

};

class Rectangle : public Shape{public:// ...double area() const{return width * height;

}// ...

};

Page 47: TDDE18 & 726G77 - Inheritance & Polymorphism

19 / 64

InheritanceLet’s add area() to Shape

int main(){Rectangle r {10, 15};cout << print_area(r) << endl; // print 0

}

Page 48: TDDE18 & 726G77 - Inheritance & Polymorphism

1 std::vector2 Inheritance3 Polymorphism4 More on Polymorphism5 Type information6 Exceptions7 Command‐line argument

Page 49: TDDE18 & 726G77 - Inheritance & Polymorphism

21 / 64

PolymorphismMany forms

Triangle r{...};Shape& ref {r};

area()

Shape

area()

Triangle

ref

Page 50: TDDE18 & 726G77 - Inheritance & Polymorphism

21 / 64

PolymorphismMany forms

Triangle r{...};Shape& ref {r};

area()

Shape

area()

Triangle

ref

Page 51: TDDE18 & 726G77 - Inheritance & Polymorphism

22 / 64

PolymorphismMany forms

class Shape{public:// ...virtual double area() const{return 0;

}// ...

};

Page 52: TDDE18 & 726G77 - Inheritance & Polymorphism

23 / 64

PolymorphismNow it works!

int main(){Rectangle r {10, 15};cout << print_area(r) << endl; // prints 150

}

Page 53: TDDE18 & 726G77 - Inheritance & Polymorphism

23 / 64

PolymorphismNow it works!

int main(){Rectangle r {10, 15};cout << print_area(r) << endl; // prints 150

}

It works!!

Page 54: TDDE18 & 726G77 - Inheritance & Polymorphism

24 / 64

PolymorphismWhen can we use polymorphism?

Shape s{};Rectangle r{10, 15};Triangle t{3, 4};

Shape* ptr {&s};ptr->area(); // returns 0

ptr = &r;ptr->area(); // returns 150

ptr = &t;ptr->area(); // returns 6

Page 55: TDDE18 & 726G77 - Inheritance & Polymorphism

25 / 64

PolymorphismPointers & Polymorphism

ptr

area()

Shape

area()

Shape

area()

Shape

area()

Rectangle

area()

Shape

area()

Triangle

Page 56: TDDE18 & 726G77 - Inheritance & Polymorphism

25 / 64

PolymorphismPointers & Polymorphism

ptr

area()

Shape

area()

Shape

area()

Shape

area()

Rectangle

area()

Shape

area()

Triangle

Page 57: TDDE18 & 726G77 - Inheritance & Polymorphism

25 / 64

PolymorphismPointers & Polymorphism

ptr

area()

Shape

area()

Shape

area()

Shape

area()

Rectangle

area()

Shape

area()

Triangle

Page 58: TDDE18 & 726G77 - Inheritance & Polymorphism

25 / 64

PolymorphismPointers & Polymorphism

ptr

area()

Shape

area()

Shape

area()

Shape

area()

Rectangle

area()

Shape

area()

Triangle

Page 59: TDDE18 & 726G77 - Inheritance & Polymorphism

26 / 64

PolymorphismThere are pitfalls...

class Cuboid : public Shape{public:Cuboid(double width, double height, double depth): Shape{width, height}, depth{depth}

{ }

double area() const{return 2.0 * (width * height + width * depth + height * depth);

}

private:double depth;

};

Page 60: TDDE18 & 726G77 - Inheritance & Polymorphism

26 / 64

PolymorphismThere are pitfalls...

Cuboid c{5, 7, 3};Shape s {c}; // slicing

width 5

height 7

area()

Shape

depth 3

area()

Cuboid

Page 61: TDDE18 & 726G77 - Inheritance & Polymorphism

26 / 64

PolymorphismThere are pitfalls...

Cuboid c{5, 7, 3};Shape s {c}; // slicing

width 5

height 7

area()

Shape

depth 3

area()

Cuboid

Page 62: TDDE18 & 726G77 - Inheritance & Polymorphism

26 / 64

PolymorphismThere are pitfalls...

Cuboid c{5, 7, 3};Shape s {c}; // slicing

width 5

height 7

area()

Shape

depth 3

area()

Cuboid

width 5

height 7

area()

Shape

Page 63: TDDE18 & 726G77 - Inheritance & Polymorphism

26 / 64

PolymorphismThere are pitfalls...

Cuboid c{5, 7, 3};Shape s {c}; // slicing

width 5

height 7

area()

Shape

depth 3

area()

Cuboid

width 5

height 7

area()

Shape

Page 64: TDDE18 & 726G77 - Inheritance & Polymorphism

27 / 64

PolymorphismThere are pitfalls...

Cuboid c {2,3,4};Shape s {c};cout << s.area() << endl; // prints 0

Page 65: TDDE18 & 726G77 - Inheritance & Polymorphism

27 / 64

PolymorphismThere are pitfalls...

Cuboid c {2,3,4};Shape& s {c};cout << s.area() << endl; // prints 24

Page 66: TDDE18 & 726G77 - Inheritance & Polymorphism

28 / 64

PolymorphismRule of thumb

When calling a member function:

1. through a non‐reference

2. through a non‐pointer

3. that is non‐virtual

4. otherwise

Page 67: TDDE18 & 726G77 - Inheritance & Polymorphism

28 / 64

PolymorphismRule of thumb

When calling a member function:

1. through a non‐reference => Call the member function

2. through a non‐pointer

3. that is non‐virtual

4. otherwise

Page 68: TDDE18 & 726G77 - Inheritance & Polymorphism

28 / 64

PolymorphismRule of thumb

When calling a member function:

1. through a non‐reference => Call the member function

2. through a non‐pointer

3. that is non‐virtual

4. otherwise

Page 69: TDDE18 & 726G77 - Inheritance & Polymorphism

28 / 64

PolymorphismRule of thumb

When calling a member function:

1. through a non‐reference => Call the member function

2. through a non‐pointer => Call the member function

3. that is non‐virtual

4. otherwise

Page 70: TDDE18 & 726G77 - Inheritance & Polymorphism

28 / 64

PolymorphismRule of thumb

When calling a member function:

1. through a non‐reference => Call the member function

2. through a non‐pointer => Call the member function

3. that is non‐virtual

4. otherwise

Page 71: TDDE18 & 726G77 - Inheritance & Polymorphism

28 / 64

PolymorphismRule of thumb

When calling a member function:

1. through a non‐reference => Call the member function

2. through a non‐pointer => Call the member function

3. that is non‐virtual => Call the member function

4. otherwise

Page 72: TDDE18 & 726G77 - Inheritance & Polymorphism

28 / 64

PolymorphismRule of thumb

When calling a member function:

1. through a non‐reference => Call the member function

2. through a non‐pointer => Call the member function

3. that is non‐virtual => Call the member function

4. otherwise

Page 73: TDDE18 & 726G77 - Inheritance & Polymorphism

28 / 64

PolymorphismRule of thumb

When calling a member function:

1. through a non‐reference => Call the member function

2. through a non‐pointer => Call the member function

3. that is non‐virtual => Call the member function

4. otherwise => Call the overriden version

Page 74: TDDE18 & 726G77 - Inheritance & Polymorphism

29 / 64

PolymorphismConclusion

Always use pointers orreferences when dealingwith polymorphic objects!

Page 75: TDDE18 & 726G77 - Inheritance & Polymorphism

30 / 64

PolymorphismAnother good reason for using polymorphism

std::vector<Shape*> shapes {new Triangle{3, 4},new Rectangle{5, 6},new Cube{3, 5, 7}

};

for (Shape* shape : shapes){cout << shape->area() << endl;

}

Page 76: TDDE18 & 726G77 - Inheritance & Polymorphism

1 std::vector2 Inheritance3 Polymorphism4 More on Polymorphism5 Type information6 Exceptions7 Command‐line argument

Page 77: TDDE18 & 726G77 - Inheritance & Polymorphism

32 / 64

More on PolymorphismExample

class Complex_Shape : public Shape{public:

// ...double area() const{double sum{0.0};for (Shape* shape : shapes){sum += shape->area();

}return sum;

}private:

std::vector<Shape*> shapes;};

Page 78: TDDE18 & 726G77 - Inheritance & Polymorphism

32 / 64

More on PolymorphismExample

class Complex_Shape : public Shape{public:

// ...double area() const{double sum{0.0};for (Shape* shape : shapes){sum += shape->area();

}return sum;

}private:

std::vector<Shape*> shapes;}; shapes:

Page 79: TDDE18 & 726G77 - Inheritance & Polymorphism

32 / 64

More on PolymorphismExample

{Complex_Shape shape { ... };cout << shape.area() << endl;

} // what happens here?

shapes:

Page 80: TDDE18 & 726G77 - Inheritance & Polymorphism

32 / 64

More on PolymorphismExample

{Complex_Shape shape { ... };cout << shape.area() << endl;

} // what happens here?

Page 81: TDDE18 & 726G77 - Inheritance & Polymorphism

32 / 64

More on PolymorphismExample

{Complex_Shape shape { ... };cout << shape.area() << endl;

} // what happens here?

Memory leak

Page 82: TDDE18 & 726G77 - Inheritance & Polymorphism

33 / 64

More on PolymorphismSo we create a destructor!

class Complex_Shape : public Shape{public:

// ...~Complex_Shape(){for (Shape* shape : shapes){delete shape;

}}// ...

};

Page 83: TDDE18 & 726G77 - Inheritance & Polymorphism

34 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

area()

Shape

area()

shapes

Complex_Shape

ptr

Page 84: TDDE18 & 726G77 - Inheritance & Polymorphism

34 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

area()

Shape

area()

shapes

Complex_Shape

ptr

Page 85: TDDE18 & 726G77 - Inheritance & Polymorphism

34 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

area()

shapes

Complex_Shape

ptr

Page 86: TDDE18 & 726G77 - Inheritance & Polymorphism

34 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

area()

shapes

Complex_Shape

ptr

Page 87: TDDE18 & 726G77 - Inheritance & Polymorphism

34 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

area()

shapes

Complex_Shape

ptr

Memory leak

Page 88: TDDE18 & 726G77 - Inheritance & Polymorphism

35 / 64

More on Polymorphismvirtual‐destructor

class Shape{public:

// ...virtual ~Shape() = default;// ...

};

Page 89: TDDE18 & 726G77 - Inheritance & Polymorphism

36 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

destructor

Shape

destructor

shapes

ptr

Complex_Shape

Page 90: TDDE18 & 726G77 - Inheritance & Polymorphism

36 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

destructor

Shape

destructor

shapes

ptr

Complex_Shape

Page 91: TDDE18 & 726G77 - Inheritance & Polymorphism

36 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

destructor

Shape

destructor

shapes

ptr

Complex_Shape

Page 92: TDDE18 & 726G77 - Inheritance & Polymorphism

36 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

ptr

Page 93: TDDE18 & 726G77 - Inheritance & Polymorphism

36 / 64

More on PolymorphismWhat about now?

Shape* ptr {new Complex_Shape{...}};delete ptr;

ptr Nice!

Page 94: TDDE18 & 726G77 - Inheritance & Polymorphism

37 / 64

More on PolymorphismConclusion

Always declare thedestructor of a

polymorphic base class asvirtual!

Page 95: TDDE18 & 726G77 - Inheritance & Polymorphism

38 / 64

More on PolymorphismSometimes humans make mistakes...

class My_Shape : public Shape{public:// ...double arae(){return 10.0;

}// ...

};

Page 96: TDDE18 & 726G77 - Inheritance & Polymorphism

38 / 64

More on PolymorphismSometimes humans make mistakes...

Shape* ptr {new My_Shape{}};cout << ptr->area() << endl;delete ptr;

Page 97: TDDE18 & 726G77 - Inheritance & Polymorphism

38 / 64

More on PolymorphismSometimes humans make mistakes...

Shape* ptr {new My_Shape{}};cout << ptr->area() << endl; // prints 0 (?!)delete ptr;

Page 98: TDDE18 & 726G77 - Inheritance & Polymorphism

38 / 64

More on PolymorphismSometimes humans make mistakes...

class My_Shape : public Shape{public:// ...double arae(){return 10.0;

}// ...

};

Aha! A misspelling!

Page 99: TDDE18 & 726G77 - Inheritance & Polymorphism

38 / 64

More on PolymorphismSometimes humans make mistakes...

class My_Shape : public Shape{public:// ...double area(){return 10.0;

}// ...

};

Page 100: TDDE18 & 726G77 - Inheritance & Polymorphism

38 / 64

More on PolymorphismSometimes humans make mistakes...

Shape* ptr {new My_Shape{}};cout << ptr->area() << endl;delete ptr;

Page 101: TDDE18 & 726G77 - Inheritance & Polymorphism

38 / 64

More on PolymorphismSometimes humans make mistakes...

Shape* ptr {new My_Shape{}};cout << ptr->area() << endl; // STILL 0 ?!delete ptr;

Page 102: TDDE18 & 726G77 - Inheritance & Polymorphism

38 / 64

More on PolymorphismSometimes humans make mistakes...

class My_Shape : public Shape{public:// ...double area() const{return 10.0;

}// ...

};

We forgot const!

Page 103: TDDE18 & 726G77 - Inheritance & Polymorphism

38 / 64

More on PolymorphismSometimes humans make mistakes...

Shape* ptr {new My_Shape{}};cout << ptr->area() << endl; // prints 10delete ptr;

Page 104: TDDE18 & 726G77 - Inheritance & Polymorphism

39 / 64

More on PolymorphismCan’t the compiler help us with these simple mistakes?

class My_Shape : public Shape{public:// ...double arae() override{return 10.0;

}// ...

};

Page 105: TDDE18 & 726G77 - Inheritance & Polymorphism

39 / 64

More on PolymorphismCan’t the compiler help us with these simple mistakes?

shape.cc: error: ‘double My_Shape::arae()’ marked ‘override’,but does not override

double arae() override^~~~

Page 106: TDDE18 & 726G77 - Inheritance & Polymorphism

40 / 64

More on PolymorphismRule of thumb

Always mark functionsthat are meant to override

as override!

Page 107: TDDE18 & 726G77 - Inheritance & Polymorphism

41 / 64

More on PolymorphismLet’s go back to Shape

class Shape{public:

// ...virtual ~Shape() = default;virtual double area() const{return 0;

}// ...

};

Page 108: TDDE18 & 726G77 - Inheritance & Polymorphism

42 / 64

More on Polymorphismpure‐virtual function

class Shape{public:

// ...virtual ~Shape() = default;virtual double area() const = 0;

};

Page 109: TDDE18 & 726G77 - Inheritance & Polymorphism

43 / 64

More on PolymorphismAbstract class

A class is abstract if it contains one or more pure‐virtualfunctions

Page 110: TDDE18 & 726G77 - Inheritance & Polymorphism

44 / 64

More on PolymorphismAbstract class

Shape s1{1, 3}; // Error: abstractTriangle t{1,3}; // OK: not abstractShape s2{t}; // Error: abstractShape& s3{t}; // OK: reference allowedShape* s4{&t}; // OK: pointer allowed

Page 111: TDDE18 & 726G77 - Inheritance & Polymorphism

45 / 64

More on PolymorphismImporting things from the base class

class Shape{public:

Shape(double w, double h): width{w}, height{h}

{}

// ...

protected:

double width;double height;

};

class Rectangle : public Shape{public:

// create an identical constructor// as the one in Shapeusing Shape::Shape;

// make width public in Rectangleusing Shape::width;

private:

// make height private in Rectangleusing Shape::height;

};

Page 112: TDDE18 & 726G77 - Inheritance & Polymorphism

1 std::vector2 Inheritance3 Polymorphism4 More on Polymorphism5 Type information6 Exceptions7 Command‐line argument

Page 113: TDDE18 & 726G77 - Inheritance & Polymorphism

47 / 64

Type informationStatic vs Dynamic type

Shape* ptr {new Triangle{3, 5}};cout << ptr->area() << endl;

delete ptr;ptr = new Rectangle{3, 5};

Static:Dynamic:

Page 114: TDDE18 & 726G77 - Inheritance & Polymorphism

47 / 64

Type informationStatic vs Dynamic type

Shape* ptr {new Triangle{3, 5}};cout << ptr->area() << endl;

delete ptr;ptr = new Rectangle{3, 5};

Static:Dynamic:

Page 115: TDDE18 & 726G77 - Inheritance & Polymorphism

47 / 64

Type informationStatic vs Dynamic type

Shape* ptr {new Triangle{3, 5}};cout << ptr->area() << endl;

delete ptr;ptr = new Rectangle{3, 5};

Static: Shape*

Dynamic:

Page 116: TDDE18 & 726G77 - Inheritance & Polymorphism

47 / 64

Type informationStatic vs Dynamic type

Shape* ptr {new Triangle{3, 5}};cout << ptr->area() << endl;

delete ptr;ptr = new Rectangle{3, 5};

Static: Shape*

Dynamic:

Page 117: TDDE18 & 726G77 - Inheritance & Polymorphism

47 / 64

Type informationStatic vs Dynamic type

Shape* ptr {new Triangle{3, 5}};cout << ptr->area() << endl;

delete ptr;ptr = new Rectangle{3, 5};

Static: Shape*

Dynamic: Triangle

Page 118: TDDE18 & 726G77 - Inheritance & Polymorphism

47 / 64

Type informationStatic vs Dynamic type

Shape* ptr {new Triangle{3, 5}};cout << ptr->area() << endl;

delete ptr;ptr = new Rectangle{3, 5};

Static: Shape*

Dynamic: Triangle

Page 119: TDDE18 & 726G77 - Inheritance & Polymorphism

47 / 64

Type informationStatic vs Dynamic type

Shape* ptr {new Triangle{3, 5}};cout << ptr->area() << endl;

delete ptr;ptr = new Rectangle{3, 5};

Static: Shape*

Dynamic: Rectangle

Page 120: TDDE18 & 726G77 - Inheritance & Polymorphism

48 / 64

Type informationExample

class Cuboid : public Shape{public:// ...virtual double volume() const{return width * height * depth;

}//...

};

Page 121: TDDE18 & 726G77 - Inheritance & Polymorphism

48 / 64

Type informationExample

Shape* ptr {new Cuboid{3, 4, 5}};

// doesn't work, volume is not// declared in Shapecout << ptr->volume() << endl;

Page 122: TDDE18 & 726G77 - Inheritance & Polymorphism

49 / 64

Type informationExample

Shape* ptr {new Cuboid{3, 4, 5}};

cout << static_cast<Cuboid*>(ptr)->volume()<< endl;

Page 123: TDDE18 & 726G77 - Inheritance & Polymorphism

50 / 64

Type informationWhen it all comes crashing down...

Shape* ptr {new Rectangle{3, 4}};

cout << static_cast<Cuboid*>(ptr)->volume()<< endl;

Page 124: TDDE18 & 726G77 - Inheritance & Polymorphism

50 / 64

Type informationWhen it all comes crashing down...

Shape* ptr {new Rectangle{3, 4}};

cout << static_cast<Cuboid*>(ptr)->volume()<< endl;

Segmentation Fault

Page 125: TDDE18 & 726G77 - Inheritance & Polymorphism

51 / 64

Type informationdynamic_cast

Shape* ptr1 {new Cuboid{3, 4, 5}};Shape* ptr2 {new Rectangle{3, 4}};

Cuboid* c1 {dynamic_cast<Cuboid*>(ptr1)};Cuboid* c2 {dynamic_cast<Cuboid*>(ptr2)};

// c1 is a pointer to a valid Cuboid object

// c2 == nullptr, since ptr2 does not// point to a valid Cuboid object

Page 126: TDDE18 & 726G77 - Inheritance & Polymorphism

52 / 64

Type informationChecking if dynamic type is compatible

Shape* ptr {...};

Cuboid* cuboid {dynamic_cast<Cuboid*>(ptr)};if (cuboid != nullptr){// only print volume if it is a cuboidcout << cuboid->volume() << endl;

}

Page 127: TDDE18 & 726G77 - Inheritance & Polymorphism

53 / 64

Type informationAlso works with references!

Cuboid c {3,4,5};Shape& s {c};

cout << dynamic_cast<Cuboid&>(s).volume() << endl;

Page 128: TDDE18 & 726G77 - Inheritance & Polymorphism

53 / 64

Type informationAlso works with references!

Rectangle r {3,4};Shape& s {c};

cout << dynamic_cast<Cuboid&>(s).volume() << endl;

Page 129: TDDE18 & 726G77 - Inheritance & Polymorphism

53 / 64

Type informationAlso works with references!

$ g++ shape.cc$ ./a.outterminate called after throwing an instance of 'std::bad_cast'what(): std::bad_cast

Aborted (core dumped)

Page 130: TDDE18 & 726G77 - Inheritance & Polymorphism

1 std::vector2 Inheritance3 Polymorphism4 More on Polymorphism5 Type information6 Exceptions7 Command‐line argument

Page 131: TDDE18 & 726G77 - Inheritance & Polymorphism

55 / 64

ExceptionsWhat just happend?!

‚ References cannot be empty

‚ What do we do to signal error?

‚ Exceptions!

Page 132: TDDE18 & 726G77 - Inheritance & Polymorphism

55 / 64

ExceptionsWhat just happend?!

‚ References cannot be empty

‚ What do we do to signal error?

‚ Exceptions!

Page 133: TDDE18 & 726G77 - Inheritance & Polymorphism

55 / 64

ExceptionsWhat just happend?!

‚ References cannot be empty

‚ What do we do to signal error?

‚ Exceptions!

Page 134: TDDE18 & 726G77 - Inheritance & Polymorphism

55 / 64

ExceptionsWhat just happend?!

‚ References cannot be empty

‚ What do we do to signal error?

‚ Exceptions!

Page 135: TDDE18 & 726G77 - Inheritance & Polymorphism

56 / 64

ExceptionsModel

int main(){try{fun1();// ...

}catch (std::exception& e){cerr << e.what();

}}

void fun1(){// ...fun2();// ...return;

}

void fun2(){return;

}

Page 136: TDDE18 & 726G77 - Inheritance & Polymorphism

56 / 64

ExceptionsModel

int main(){try{fun1();// ...

}catch (std::exception& e){cerr << e.what();

}}

void fun1(){// ...fun2();// ...return;

}

void fun2(){return;

}

Page 137: TDDE18 & 726G77 - Inheritance & Polymorphism

56 / 64

ExceptionsModel

int main(){try{fun1();// ...

}catch (std::exception& e){cerr << e.what();

}}

void fun1(){// ...fun2();// ...return;

}

void fun2(){return;

}

Page 138: TDDE18 & 726G77 - Inheritance & Polymorphism

56 / 64

ExceptionsModel

int main(){try{fun1();// ...

}catch (std::exception& e){cerr << e.what();

}}

void fun1(){// ...fun2();// ...return;

}

void fun2(){return;

}

Page 139: TDDE18 & 726G77 - Inheritance & Polymorphism

56 / 64

ExceptionsModel

int main(){try{fun1();// ...

}catch (std::exception& e){cerr << e.what();

}}

void fun1(){// ...fun2();// ...return;

}

void fun2(){return;

}

Page 140: TDDE18 & 726G77 - Inheritance & Polymorphism

56 / 64

ExceptionsModel

int main(){try{fun1();// ...

}catch (std::exception& e){cerr << e.what();

}}

void fun1(){// ...fun2();// ...return;

}

void fun2(){throw std::exception{""};

}

Page 141: TDDE18 & 726G77 - Inheritance & Polymorphism

56 / 64

ExceptionsModel

int main(){try{fun1();// ...

}catch (std::exception& e){cerr << e.what();

}}

void fun1(){// ...fun2();// ...return;

}

void fun2(){throw std::exception{""};

}

Page 142: TDDE18 & 726G77 - Inheritance & Polymorphism

56 / 64

ExceptionsModel

int main(){try{fun1();// ...

}catch (std::exception& e){cerr << e.what();

}}

void fun1(){// ...fun2();// ...return;

}

void fun2(){throw std::exception{""};

}

Page 143: TDDE18 & 726G77 - Inheritance & Polymorphism

56 / 64

ExceptionsModel

int main(){try{fun1();// ...

}catch (std::exception& e){cerr << e.what();

}}

void fun1(){// ...fun2();// ...return;

}

void fun2(){throw std::exception{""};

}

Page 144: TDDE18 & 726G77 - Inheritance & Polymorphism

57 / 64

Exceptionsdynamic_cast

#include <stdexcept>

int main(){Rectangle r {3,4};Shape& s {c};

try{cout << dynamic_cast<Cuboid&>(s).volume() << endl;

}catch (std::bad_cast& e){cout << "s is not a Cuboid!" << endl;

}catch (std::exception& e){cout << "Unknown error." << endl;

}}

Page 145: TDDE18 & 726G77 - Inheritance & Polymorphism

1 std::vector2 Inheritance3 Polymorphism4 More on Polymorphism5 Type information6 Exceptions7 Command‐line argument

Page 146: TDDE18 & 726G77 - Inheritance & Polymorphism

59 / 64

Command‐line argumentCalling a program with arguments

$ ./a.out a b c

Page 147: TDDE18 & 726G77 - Inheritance & Polymorphism

59 / 64

Command‐line argumentCalling a program with arguments

$ ./a.out a b c

Arguments: a, b, c

Page 148: TDDE18 & 726G77 - Inheritance & Polymorphism

60 / 64

Command‐line argumentReading arguments

int main(int argc, char* argv[]){

// argc = number of arguments passed to the program// argv = a pointer to an array of pointers to C-strings

}

Page 149: TDDE18 & 726G77 - Inheritance & Polymorphism

61 / 64

Command‐line argumentargv

$ a.out a b c

a . o u t \0 a \0 b \0 c \0

argv: argc: 4

Page 150: TDDE18 & 726G77 - Inheritance & Polymorphism

62 / 64

Command‐line argumentExample

int main(int argc, char** argv){for (int i{0}; i < argc; ++i){cout << argv[i] << endl;

}}

Page 151: TDDE18 & 726G77 - Inheritance & Polymorphism

62 / 64

Command‐line argumentExample

$ ./a.out 10 20 30./a.out102030

Page 152: TDDE18 & 726G77 - Inheritance & Polymorphism

63 / 64

Command‐line argumentConverting arguments

‚ std::stoi(argv[1]) ‐ convert argv[1] to int

‚ std::stod(argv[1]) ‐ convert argv[1] to double

‚ Using std::stringstream:

std::stringstream ss{};ss << argv[1];

int number;ss >> number;

Page 153: TDDE18 & 726G77 - Inheritance & Polymorphism

64 / 64

Command‐line argumentCool trick

vector<string> args { argv, argv + argc };// now all arguments reside in the vector// as std::string instead of C-strings

Page 154: TDDE18 & 726G77 - Inheritance & Polymorphism

www.liu.se