Download presentation
Presentation is loading. Please wait.
1
Jeff West - Quiz Section 12
CSE 143 Section AD Quiz Section 12 7/26/2001 Jeff West - Quiz Section 12
2
Jeff West - Quiz Section 12
Announcements Quiz at the end of section on Inheritance and Dynamic Dispatch 7/26/2001 Jeff West - Quiz Section 12
3
Jeff West - Quiz Section 12
Substitution A derived class can ALWAYS be substituted for a base class. However, the behavior of a substituted class depends on the type of the methods you’re calling. 7/26/2001 Jeff West - Quiz Section 12
4
What does this print to the screen? (No virtual functions)
void Shape::draw() { cout << “Hi, I’m a shape!”; } void Rectangle::draw() { cout << “Hi, I’m a rectangle!”; void drawShape(Shape myShape) { myShape.draw(); Shape myShape; Circle myRectangle(GREEN, 20, 10); myShape = myRectangle; drawShape(myShape); drawShape(myRectangle); 7/26/2001 Jeff West - Quiz Section 12
5
And this??? (No virtual functions)
void Shape::draw() { cout << “Hi, I’m a shape!”; } void Rectangle::draw() { cout << “Hi, I’m a rectangle!”; void drawShape(Shape* myShape) { myShape->draw(); Shape* myShape; Circle* myRectangle = new Rectangle(GREEN, 20, 10); myShape = myRectangle; drawShape(myShape); drawShape(myRectangle); 7/26/2001 Jeff West - Quiz Section 12
6
What if we want the drawShape function to…
We can make it so that the drawShape function would call the draw() method of the run-time type that is passed in! To do this, we need only to declare the function virtual in the base class (Shape in our example)… 7/26/2001 Jeff West - Quiz Section 12
7
What does this print to the screen? (Virtual functions!)
void Shape::draw() { cout << “Hi, I’m a shape!”; } void Rectangle::draw() { cout << “Hi, I’m a rectangle!”; void drawShape(Shape myShape) { myShape.draw(); Shape myShape; Circle myRectangle(GREEN, 20, 10); myShape = myRectangle; drawShape(myShape); drawShape(myRectangle); 7/26/2001 Jeff West - Quiz Section 12
8
Jeff West - Quiz Section 12
To take advantage… To take advantage of virtual functions you need to use pointers to objects. Otherwise, information is lost! The most common use for all of this is to have one large array of one object type (e.g. vehicles) that have many “sub-types” that behave differently (trucks, cars, busses)… 7/26/2001 Jeff West - Quiz Section 12
9
And this??? (Virtual functions!)
void Shape::draw() { cout << “Hi, I’m a shape!”; } void Rectangle::draw() { cout << “Hi, I’m a rectangle!”; void drawShape(Shape* myShape) { myShape->draw(); Shape* myShape; Circle* myRectangle = new Rectangle(GREEN, 20, 10); myShape = myRectangle; drawShape(myShape); drawShape(myRectangle); 7/26/2001 Jeff West - Quiz Section 12
10
Pure Virtual Functions (1)
What if you never want the ability to create a shape, because it doesn’t make sense for a shape to “draw” itself… You’d call Shape an abstract class, intended only to be a skeleton for derived classes. Make functions that need to be in a child class but can’t be defined in the Shape class pure virtual! 7/26/2001 Jeff West - Quiz Section 12
11
Pure Virtual Functions (2)
Class Shape { public: … virtual void draw() = 0; }; 7/26/2001 Jeff West - Quiz Section 12
12
Jeff West - Quiz Section 12
But Why??? Without having some sort of draw() function in EVERY Shape class instance, you couldn’t: void Rectangle::draw() { cout << “Hi, I’m a rectangle!”; } void drawShape(Shape* myShape) { myShape->draw(); Shape* myShape; Circle* myRectangle = new Rectangle(GREEN, 20, 10); myShape = myRectangle; drawShape(myShape); drawShape(myRectangle); 7/26/2001 Jeff West - Quiz Section 12
13
A bit of cleaning up to do…
Always make your destructors virtual! This ensures that all dynamic memory in inherited classes is taken care of. Remember how constructors of derived classes always call the constructors of their base class before executing? Destructors always call the destructors of their base class after executing! 7/26/2001 Jeff West - Quiz Section 12
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.