Inheritance and Polymorphism Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University.

Slides:



Advertisements
Similar presentations
Copyright © 2012 Pearson Education, Inc. Chapter 15: Inheritance, Polymorphism, and Virtual Functions.
Advertisements

CPA: C++ Polymorphism Copyright © 2007 Mohamed Iqbal Pallipurath Overview of C++ Polymorphism Two main kinds of types in C++: native and user-defined –User-defined.
LECTURE LECTURE 17 More on Inheritance, Virtual Inheritance, & Virtual Destructors, 17.
CS 106 Introduction to Computer Science I 04 / 11 / 2008 Instructor: Michael Eckmann.
CS 106 Introduction to Computer Science I 11 / 26 / 2007 Instructor: Michael Eckmann.
Inheritance. Extending Classes It’s possible to create a class by using another as a starting point  i.e. Start with the original class then add methods,
Polymorphism, Virtual Methods and Abstract Classes.
Lecture 12 Destructors “Absolute C++” Chapters 10.3, 15.2.
CS 106 Introduction to Computer Science I 04 / 16 / 2010 Instructor: Michael Eckmann.
Rossella Lau Lecture 8, DCO10105, Semester B, DCO10105 Object-Oriented Programming and Design  Lecture 8: Polymorphism & C++ pointer  Inheritance.
CS 106 Introduction to Computer Science I 11 / 15 / 2006 Instructor: Michael Eckmann.
Chapter 16 Templates. Copyright © 2006 Pearson Addison-Wesley. All rights reserved Learning Objectives  Function Templates  Syntax, defining 
Inheritance, Polymorphism, and Virtual Functions
Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.
CSE 332: C++ Classes From Procedural to Object-oriented Programming Procedural programming –Functions have been the main focus so far Function parameters.
C++ Programming: Program Design Including Data Structures, Fourth Edition Chapter 13: Pointers, Classes, Virtual Functions, and Abstract Classes.
Pointer Data Type and Pointer Variables
Inheritance in C++ CS-1030 Dr. Mark L. Hornick.
CSE 425: Object-Oriented Programming II Implementation of OO Languages Efficient use of instructions and program storage –E.g., a C++ object is stored.
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Taken from slides of Starting Out with C++ Early Objects Seventh Edition.
C++ Programming: From Problem Analysis to Program Design, Fourth Edition Chapter 14: Pointers, Classes, Virtual Functions, and Abstract Classes.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Slide
CSE 332: C++ templates This Week C++ Templates –Another form of polymorphism (interface based) –Let you plug different types into reusable code Assigned.
Programming in Java Unit 2. Class and variable declaration A class is best thought of as a template from which objects are created. You can create many.
Object Oriented Programming with C++/ Session 6 / 1 of 44 Multiple Inheritance and Polymorphism Session 6.
Method Overriding Remember inheritance: when a child class inherits methods, variables, etc from a parent class. Example: public class Dictionary extends.
Copyright © 2012 Pearson Education, Inc. Chapter 13: Introduction to Classes.
Copyright © 2009 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 13: Introduction to Classes.
Week 14 - Monday.  What did we talk about last time?  Introduction to C++  Input and output  Functions  Overloadable  Default parameters  Pass.
1 Advanced Issues on Classes Part 3 Reference variables (Tapestry pp.581, Horton 176 – 178) Const-reference variables (Horton 176 – 178) object sharing:
Linked Lists part 2 CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer Science University.
Hank Childs, University of Oregon May 13th, 2015 CIS 330: _ _ _ _ ______ _ _____ / / / /___ (_) __ ____ _____ ____/ / / ____/ _/_/ ____/__ __ / / / / __.
Pointer and Array Lists Chapter 3, Summary CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and.
Chapter 12: Pointers, Classes, Virtual Functions, and Abstract Classes.
C++ and Ubuntu Linux Review and Practice CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and.
Polymorphism and Virtual Functions. Topics Polymorphism Virtual Functions Pure Virtual Functions Abstract Base Classes Virtual Destructors V-Tables Run.
Object Oriented Programming Elhanan Borenstein Lecture #3 copyrights © Elhanan Borenstein.
CSCI-383 Object-Oriented Programming & Design Lecture 18.
CS 376b Introduction to Computer Vision 01 / 23 / 2008 Instructor: Michael Eckmann.
Copyright © 2012 Pearson Education, Inc. Chapter 15: Inheritance, Polymorphism, and Virtual Functions.
CPSC 252 The Big Three Page 1 The “Big Three” Every class that has data members pointing to dynamically allocated memory must implement these three methods:
References and Pointers CS 244 Connect Speakers for this Presentation Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics,
CS-1030 Dr. Mark L. Hornick 1 Basic C++ State the difference between a function/class declaration and a function/class definition. Explain the purpose.
Advanced Classes and Dynamic Memory Allocation Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and.
Copyright © 2008 Pearson Addison-Wesley. All rights reserved. Chapter 15 Inheritance.
CS 106 Introduction to Computer Science I 04 / 18 / 2008 Instructor: Michael Eckmann.
Inheritance Initialization & Destruction of Derived Objects Protected Members Non-public Inheritance Virtual Function Implementation Virtual Destructors.
LECTURE LECTURE 11 Constructors and destructors Copy constructor Textbook: p , 183.
Classes, Interfaces and Packages
Overview of C++ Polymorphism
Reading from a file, Sorting, and a little Searching Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics,
Fall 2015CISC/CMPE320 - Prof. McLeod1 CISC/CMPE320 Assignment 3 is due Sunday, the 8 th at 7pm. Problems with assn 3? Discuss at your team meeting tonight.
CSE 332: C++ pointers, arrays, and references Overview of Pointers and References Often need to refer to another object –Without making a copy of the object.
Recap Introduction to Inheritance Inheritance in C++ IS-A Relationship Polymorphism in Inheritance Classes in Inheritance Visibility Rules Constructor.
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 223 – Advanced Data Structures C++ Review 2.
Terms and Rules II Professor Evan Korth New York University (All rights reserved)
Polymorphism and Virtual Functions One name many shapes behaviour Unit - 07.
Chapter 16 Templates Copyright © 2008 Pearson Addison-Wesley. All rights reserved.
Linked Lists Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
Chapter 12: Pointers, Classes, Virtual Functions, Abstract Classes, and Lists.
A First Book of C++ Chapter 12 Extending Your Classes.
1 Ugly Realities The Dark Side of C++ Chapter 12.
Hank Childs, University of Oregon
Inheritance Modern object-oriented (OO) programming languages provide 3 capabilities: encapsulation inheritance polymorphism which can improve the design,
Andy Wang Object Oriented Programming in C++ COP 3330
Inheritance & Polymorphism
Chapter 12: Pointers, Classes, Virtual Functions, and Abstract Classes
CISC/CMPE320 - Prof. McLeod
Overview of C++ Polymorphism
Presentation transcript:

Inheritance and Polymorphism Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin – Stout Based on the book: Data Structures and Algorithms in C++ (Goodrich, Tamassia, Mount) Some content derived/taken from: and some from C++ Through Game Programming (Dawson)

Things to Note Homework 4 is Due Soon Homework 5 is Posted on D2L – Do NOT delay in starting it Do not forget to look at the Meta-Info files

From Last Time – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

For Today Review – UML Hierarchy Inheritance and Polymorphism – Some Review and Some New stuff Derive one class from another Use inherited data members and member functions Override base class member functions Define virtual functions to enable Polymorphism Glance at pure virtual functions to define abstract classes

Marker Slide Any General Questions ? Next up – UML Hierarchy (review) – C++ Inheritance (review) – Inheritance (new)

Recall: Class Activity – Vehicles Looked like: Pick-Up TruckCar Vehicle Van

Recall: UML Hierarchy And we extrapolated to: UML allows for one class to be a generalization of another – This is called an “is a” relationship For example, in the below a Student “is a” SimplePerson SimplePerson - m_nameStr: string - m_idStr string + SimplePerson(const string& nameStr, const string& idStr); + ~SimplePerson() + print() : void + getName() : string Friend functions + bool operator==(const SimplePerson& lhs, const SimplePerson& rhs) Student - m_major: string - m_gradYear: int + Student(const string& sname, const string& sid, const string& smajor, int year); + ~Student() + print(): void + changeMajor(string newMajor) :void Aside: This does not mean students are simple

Recall: C++ Hierarchy From UML Hierarchy we went to: – The Object-Oriented paradigm, which C++ follows allows for hierarchy in its classes via inheritance – In general you will develop a base class (or parent class) such as: SimplePerson – From that base class you will derive a subclass (or child class) such as: Student – A base class may have multiple subclasses such as: Student, Instructor, Administrator

Marker Slide Any questions on: – UML Hierarchy (review) Next up – C++ Inheritance (review) – Inheritance (new)

Recall: C++ Inheritance Subclasses are said to specialize or extend a base class Subclasses do NOT need to re-implement functions defined in the base class as the subclass inherits them – Subclasses can re-implement base class functions but should not need to do so Subclasses should define and declare functions that make it a specialization of the base class

Recall: Class Activity – class Student Create a C++ class Student derived from SimplePerson – Use the code in the above slides as appropriate may look on D2L also for some starter code – Be sure to create a main() routine in a file named PersonTest.cpp to test out your new classes Extra Challenge – Instead of using g++ PersonTest.cpp SimplePerson.cpp Student.cpp – Create a makefile to compile and build this program Example on D2L likely (may be in general section or examples) SimplePerson - m_nameStr: string - m_idStr string + SimplePerson(const string& nameStr, const string& idStr); + ~SimplePerson() + print() : void + getName() : string Student - m_major: string - m_gradYear: int + Student(const string& sname, const string& sid, const string& smajor, int year); + ~ Student () + print(): void + changeMajor(const string& newMajor): void

Marker Slide Any questions on: – UML Hierarchy (review) – C++ Inheritance (review) Next up – Inheritance (new) Simple Boss Overriding Boss

Definition: Inheritance Inheritance allows you to derive a new class from an existing one – The new class is a subclass, or child, of the existing class – The new class automatically inherits the data members and the member functions of an existing class

Example Use Inheritance is useful when there is a need for specialized versions of an existing class Example: – class Enemy has member variable: m_Damage member function: Attack() – Need a “Boss” type enemy that is tougher Can extend class Enemy and add: – a m_DamageMultiplier member variable – a SpecialAttack() member function m_DamageMultiplier

In-Class Activity: SimpleBoss Take a couple minutes to download the example from D2L – File: EX065_SimpleBoss.cpp Sample run should look like: Code Discussion/walkthrough follows

Looking at Simple Boss // // Simple Boss // Demonstrates inheritance // #include using namespace std; // // Declaration of class Enemy // This would normally be in the file Enemy.h // class Enemy { public: int m_Damage; Enemy(); void Attack() const; }; Enemy::Enemy(): m_Damage(10) { // nothing to do, the above instantiation list // already initialized m_Damage = 10 } // void Enemy::Attack() const { cout << "Attack inflicts " << m_Damage << " damage points!\n"; } Our typical includes and using namespace

Looking at Simple Boss // // Simple Boss // Demonstrates inheritance // #include using namespace std; // // Declaration of class Enemy // This would normally be in the file Enemy.h // class Enemy { public: int m_Damage; Enemy(); void Attack() const; }; Enemy::Enemy(): m_Damage(10) { // nothing to do, the above instantiation list // already initialized m_Damage = 10 } // void Enemy::Attack() const { cout << "Attack inflicts " << m_Damage << " damage points!\n"; } Declaration of class Enemy 1 public member variable Constructor 1 public member function

Looking at Simple Boss // // Simple Boss // Demonstrates inheritance // #include using namespace std; // // Declaration of class Enemy // This would normally be in the file Enemy.h // class Enemy { public: int m_Damage; Enemy(); void Attack() const; }; Enemy::Enemy(): m_Damage(10) { // nothing to do, the above instantiation list // already initialized m_Damage = 10 } // void Enemy::Attack() const { cout << "Attack inflicts " << m_Damage << " damage points!\n"; } Constructor function of class Enemy Notice the instantiation list : m_Damage(10) This initializes m_Damage = 10 Same Effect As: Enemy::Enemy() { m_Damage = 10; }

Looking at Simple Boss // // Simple Boss // Demonstrates inheritance // #include using namespace std; // // Declaration of class Enemy // This would normally be in the file Enemy.h // class Enemy { public: int m_Damage; Enemy(); void Attack() const; }; Enemy::Enemy(): m_Damage(10) { // nothing to do, the above instantiation list // already initialized m_Damage = 10 } // void Enemy::Attack() const { cout << "Attack inflicts " << m_Damage << " damage points!\n"; } Enemy’s Attack function The const implies no values are changed in this function (i.e. constant)

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } Declaration of class Boss derived from class Enemy and public things stay public class Boss inherits m_Damage and Attack() from class enemy

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } Declaration of class Boss derived from class Enemy and public things stay public class Boss inherits m_Damage and Attack() from class enemy It extends the class by adding the members m_DamageMultiplier and SpecialAttack()

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } Declaration of class Boss derived from class Enemy and public things stay public class Boss inherits m_Damage and Attack() from class enemy It extends the class by adding the members m_DamageMultiplier and SpecialAttack() Public Service Message Constructors Copy Constructors Destructors Overloaded assignment operators are NOT inherited from the base class

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } Constructor of the Boss class. It too has an instantiation list Which initializes m_DamageMultiplier = 3 But what is the value of m_Damage? How?

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } Constructor of the Boss class. It too has an instantiation list Which initializes m_DamageMultiplier = 3 But what is the value of m_Damage? How? Side Point Exercise Try the following code/program out and see what happens: struct A { A() {cout << "A() C-tor" << endl;} ~A(){cout << "~A() D-tor" << endl;} }; struct B : public A { B(){cout << "B() C-tor" << endl;} ~B(){cout << "~B() D-tor" << endl;} }; int main() { B b; }

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } Side Point Exercise Try the following code/program out and see what happens: struct A { A() {cout << "A() C-tor" << endl;} ~A(){cout << "~A() D-tor" << endl;} }; struct B : public A { B(){cout << "B() C-tor" << endl;} ~B(){cout << "~B() D-tor" << endl;} }; int main() { B b; } struct A has a “default” constructor i.e. one with no parameters struct B’s constructor will automatically call the default constructor for A prior to running its own constructor.

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } Side Point Exercise Try the following code/program out and see what happens: struct A { A() {cout << "A() C-tor" << endl;} ~A(){cout << "~A() D-tor" << endl;} }; struct B : public A { B(){cout << "B() C-tor" << endl;} ~B(){cout << "~B() D-tor" << endl;} }; int main() { B b; } struct A has a “default” constructor i.e. one with 0 parameters struct B’s constructor will automatically call the default constructor for A prior to running its own constructor. And we see that in the output below

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } Side Point Exercise Try the following code/program out and see what happens: struct A { A() {cout << "A() C-tor" << endl;} ~A(){cout << "~A() D-tor" << endl;} }; struct B : public A { B(){cout << "B() C-tor" << endl;} ~B(){cout << "~B() D-tor" << endl;} }; int main() { B b; } The destructors are called in reverse order. When B’s destructor completes then A’s is called automatically. Think house construction: A = foundation, B = first floor Create house = build foundation, then 1 st floor Destroy house = dest 1 st floor, then foundation

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } But what is the value of m_Damage? How? So value of m_Damage is set to 10 because Enemy’s default constructor is automatically called by Boss’s constructor before it executes its own body of code.

Looking at Simple Boss // // Declaration of class Boss // Normally this would be done in file: Boss.h // Notice it is derived from the class Enemy // class Boss : public Enemy { public: int m_DamageMultiplier; Boss(); void SpecialAttack() const; }; // // Implementation of the class Boss // Normally this would be done in the file: Boss.cpp // Boss::Boss(): m_DamageMultiplier(3) { // nothing to do here. The above instantiation list // already initialized m_DamageMultiplier = 3 } // void Boss::SpecialAttack() const { cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n"; } SpecialAttack function again const implies no values will change in this function (i.e constant)

Looking at Simple Boss // // main function // Normally this would be found in a separate.cpp file // perhaps named BossTest.cpp // int main() { cout << "Creating an enemy.\n"; Enemy enemy1; enemy1.Attack(); cout << "\nCreating a boss.\n"; Boss boss1; boss1.Attack(); boss1.SpecialAttack(); return 0; } The main() function Creates a variable of type Enemy And calls its Atttack() function

Looking at Simple Boss // // main function // Normally this would be found in a separate.cpp file // perhaps named BossTest.cpp // int main() { cout << "Creating an enemy.\n"; Enemy enemy1; enemy1.Attack(); cout << "\nCreating a boss.\n"; Boss boss1; boss1.Attack(); boss1.SpecialAttack(); return 0; } The main() function It then creates a variable of type Boss and calls its Attack and SpecialAttack functions

Marker Slide Any questions on: – UML Hierarchy (review) – C++ Inheritance (review) – Inheritance (new) Simple Boss Next up – Inheritance (new) Overriding Boss – Polymorphism (new) Polymorphic Bad Guy

In-Class Activity: Overriding Boss Take a couple minutes to download the example from D2L – File: EX069_OverridingBoss.cpp Sample run should look like: Code Discussion/walkthrough follows

Looking at Overriding Boss //Overriding Boss //Demonstrates calling and overriding base member functions #include using namespace std; // // Enemy Interface Declaration // Typically found in Enemy.h, // everything is grouped together here for ease of presentation // class Enemy { public: Enemy(int damage = 10); void virtual Taunt() const; //made virtual to be overridden void virtual Attack() const; //made virtual to be overridden private: int m_Damage; }; Standard include for IO Using standard namespace

Looking at Overriding Boss //Overriding Boss //Demonstrates calling and overriding base member functions #include using namespace std; // // Enemy Interface Declaration // Typically found in Enemy.h, // everything is grouped together here for ease of presentation // class Enemy { public: Enemy(int damage = 10); void virtual Taunt() const; //made virtual to be overridden void virtual Attack() const; //made virtual to be overridden private: int m_Damage; }; Class Enemy Constructor sets default value for damage to 10

Looking at Overriding Boss //Overriding Boss //Demonstrates calling and overriding base member functions #include using namespace std; // // Enemy Interface Declaration // Typically found in Enemy.h, // everything is grouped together here for ease of presentation // class Enemy { public: Enemy(int damage = 10); void virtual Taunt() const; //made virtual to be overridden void virtual Attack() const; //made virtual to be overridden private: int m_Damage; }; Enemy(int damage = 10) Works like TWO constructors The first has zero parameters Enemy someGuy; The compiler will automatically change that to be the same as: Enemy someGuy(10);

Looking at Overriding Boss //Overriding Boss //Demonstrates calling and overriding base member functions #include using namespace std; // // Enemy Interface Declaration // Typically found in Enemy.h, // everything is grouped together here for ease of presentation // class Enemy { public: Enemy(int damage = 10); void virtual Taunt() const; //made virtual to be overridden void virtual Attack() const; //made virtual to be overridden private: int m_Damage; }; Enemy(int damage = 10) Works like TWO constructors The second has one parameters Enemy someGuy(88); with results as would be expected.

Looking at Overriding Boss //Overriding Boss //Demonstrates calling and overriding base member functions #include using namespace std; // // Enemy Interface Declaration // Typically found in Enemy.h, // everything is grouped together here for ease of presentation // class Enemy { public: Enemy(int damage = 10); void virtual Taunt() const; //made virtual to be overridden void virtual Attack() const; //made virtual to be overridden private: int m_Damage; }; Virtual Functions The keyword virtual means these functions are intended to be overridden by subclasses. This supports polymorphism.

Looking at Overriding Boss // // Enemy Implementation Definition // Typically found in Enemy.cpp, // everything is grouped together here for ease of presentation // // Constructor // Enemy::Enemy(int damage):m_Damage(damage) { // nothing left to do } // void Enemy::Taunt() const { cout << "The enemy says he will fight you.\n"; } // void Enemy::Attack() const { cout << "Attack! Inflicts " << m_Damage << " damage points."; } Note the instantiation list :m_Damage(damage) This is the same as saying m_Damage = damage; in the body of the constructor

Looking at Overriding Boss // // Enemy Implementation Definition // Typically found in Enemy.cpp, // everything is grouped together here for ease of presentation // // Constructor // Enemy::Enemy(int damage):m_Damage(damage) { // nothing left to do } // void Enemy::Taunt() const { cout << "The enemy says he will fight you.\n"; } // void Enemy::Attack() const { cout << "Attack! Inflicts " << m_Damage << " damage points."; } Member functions with basic output lines to the screen. Recall these were declared as virtual Note the words used as they will not be the same as the soon to be revealed “Boss” class

Looking at Overriding Boss // // Interface Declaration for // Boss class derived from Enemy class // Again typically this would be in Boss.h // class Boss : public Enemy { public: Boss(int damage = 30); void virtual Taunt() const; //optional use of keyword virtual void virtual Attack() const; //optional use of keyword virtual }; class Enemy { public: Enemy(int damage = 10); void virtual Taunt() const; //made virtual to be overridden void virtual Attack() const; //made virtual to be overridden private: int m_Damage; }; Interface for Boss class derived from Enemy Notice almost same as Enemy class. Constructor initializes damage to 30 virtual keyword kept No re-declaration of member variable: m_Damage

Looking at Overriding Boss // // Implementation Definition of Boss class // Again typically this would be in Boss.cpp // // Boss's Constructor // Boss::Boss(int damage): Enemy(damage) // call base class constructor with argument { } For the Boss’s constructor the instantiation list does something special: It calls the base class constructor sending it the damage parameter This is one of the few ways you can ever directly “call” a class’s constructor In thought this is same as: Boss:Boss(int damage) { Enemy::Enemy(damage);  you should not actually do this }

Looking at Overriding Boss // void Boss::Taunt() const //override base class member function { cout << "The boss says he will end your pitiful existence.\n"; } // void Boss::Attack() const //override base class member function { Enemy::Attack(); //call base class member function cout << " And laughs heartily at you.\n"; } Here are the overridden virtual functions Notice the output is different than that of the Enemy functions of the same name void Enemy::Taunt() const { cout << "The enemy says he will fight you.\n"; } void Enemy::Attack() const { cout << "Attack! Inflicts " << m_Damage << " damage points."; }

Looking at Overriding Boss // void Boss::Taunt() const //override base class member function { cout << "The boss says he will end your pitiful existence.\n"; } // void Boss::Attack() const //override base class member function { Enemy::Attack(); //call base class member function cout << " And laughs heartily at you.\n"; } Other point of note The Boss::Attack function first calls the base class’s Attack function and then adds an extra message after it void Enemy::Taunt() const { cout << "The enemy says he will fight you.\n"; } void Enemy::Attack() const { cout << "Attack! Inflicts " << m_Damage << " damage points."; }

Looking at Overriding Boss // // main - it all begins here // This would also typically be in a separate file, e.g. BossTester.cpp // int main() { cout << "Enemy object:\n"; Enemy anEnemy; anEnemy.Taunt(); anEnemy.Attack(); cout << "\n\nBoss object:\n"; Boss aBoss; aBoss.Taunt(); aBoss.Attack(); return 0; } The main() function Creates an “Enemy” Creates a “Boss” Compare the output of the Taunt and Attack Functions

Marker Slide Any questions on: – UML Hierarchy (review) – C++ Inheritance (review) – Inheritance (new) Simple Boss Overriding Boss Next up – Polymorphism (new) Polymorphic Bad Guy – Blackjack Game

Polymorphism Conversational definition of Polymorphism: – A member function will produce different results depending on the type of object for which it is being called Example – 10 bad guys face the player – Each of a different class type – Call the attack() function for each and get 10 different (class specific attacks) requires use of keyword virtual

In-Class Activity: Poly Bad Guy Take a couple minutes to download the example from D2L – File: EX072_PolymorphBadGuy.cpp Sample run should look like: Code Discussion/walkthrough follows

Looking at Poly Bad Guy // // Polymorphic Bad Guy // Demonstrates calling member functions dynamically // #include using namespace std; // class Enemy { public: Enemy(int damage = 10); virtual ~Enemy(); void virtual Attack() const; protected: int* mp_Damage; }; Code setup is similar to previous example Note a destructor is declared and the use of virtual and the m_Damage is now a pointer named mp_Damage

Looking at Poly Bad Guy // Enemy::Enemy(int damage) { mp_Damage = new int(damage); } // Enemy::~Enemy() { cout << "In Enemy destructor, deleting mp_Damage.\n"; delete mp_Damage; mp_Damage = 0; } Constructor is dynamically allocating memory

Looking at Poly Bad Guy // Enemy::Enemy(int damage) { mp_Damage = new int(damage); } // Enemy::~Enemy() { cout << "In Enemy destructor, deleting mp_Damage.\n"; delete mp_Damage; mp_Damage = NULL; } Destructor is freeing/deleting the dynamically allocated memory and setting the pointer to NULL

Looking at Poly Bad Guy // void Enemy::Attack() const { cout << "An enemy attacks and inflicts " << *mp_Damage << " damage points."; } Outputs the damage of the attack. Note the * dereferences the mp_Damage pointer variable

Looking at Poly Bad Guy // class Boss : public Enemy { public: Boss(int multiplier = 3); virtual ~Boss(); void virtual Attack() const; protected: int* mp_Multiplier; }; Interface Declaration for Boss class Again has a destructor and uses the keyword virtual The damage multiplier member variable is a pointer to type int

Looking at Poly Bad Guy // Boss::Boss(int multiplier) { mp_Multiplier = new int(multiplier); } // Boss::~Boss() { cout << "In Boss destructor, deleting mp_Multiplier.\n"; delete mp_Multiplier; mp_Multiplier = NULL; } The Boss’s constructor allocates memory for the mp_Multiplier Recall the Enemy’s constructor is automatically called prior to the running of the Boss’s constructor

Looking at Poly Bad Guy // Boss::Boss(int multiplier) { mp_Multiplier = new int(multiplier); } // Boss::~Boss() { cout << "In Boss destructor, deleting mp_Multiplier.\n"; delete mp_Multiplier; mp_Multiplier = NULL; } The Boss’s destructor frees the memory used by the mp_Multiplier pointer variable and sets it to NULL. Recall the Enemy’s destructor will be called automatically after the Boss’s destructor executes

Looking at Poly Bad Guy void Boss::Attack() const { cout << "A boss attacks and inflicts " << (*mp_Damage) * (*mp_Multiplier) << " damage points."; } The Boss’s attack function Notice the output is significantly different than that of a basic Enemy Note also the dereferencing of the pointer variables using *

Looking at Poly Bad Guy // // main - it all begins here // int main() { cout << "Calling Attack() on Boss object through pointer to Enemy:\n"; Enemy* pBadGuy = new Boss(); pBadGuy->Attack(); cout << "\n\nDeleting pointer to Enemy:\n"; delete pBadGuy; pBadGuy = NULL; return 0; } We declare a pointer to class Enemy

Looking at Poly Bad Guy // // main - it all begins here // int main() { cout << "Calling Attack() on Boss object through pointer to Enemy:\n"; Enemy* pBadGuy = new Boss(); pBadGuy->Attack(); cout << "\n\nDeleting pointer to Enemy:\n"; delete pBadGuy; pBadGuy = NULL; return 0; } We declare a pointer to class Enemy But we allocate a class Boss

Looking at Poly Bad Guy // // main - it all begins here // int main() { cout << "Calling Attack() on Boss object through pointer to Enemy:\n"; Enemy* pBadGuy = new Boss(); pBadGuy->Attack(); cout << "\n\nDeleting pointer to Enemy:\n"; delete pBadGuy; pBadGuy = NULL; return 0; } We declare a pointer to class Enemy But we allocate a class Boss So which Attack() function executes here?

Looking at Poly Bad Guy // // main - it all begins here // int main() { cout << "Calling Attack() on Boss object through pointer to Enemy:\n"; Enemy* pBadGuy = new Boss(); pBadGuy->Attack(); cout << "\n\nDeleting pointer to Enemy:\n"; delete pBadGuy; pBadGuy = NULL; return 0; } We declare a pointer to class Enemy But we allocate a class Boss So which Attack() function executes here? By Polymorphism and the use of the keyword virtual Boss’s Attack function will “magically” be executed

Looking at Poly Bad Guy // // main - it all begins here // int main() { cout << "Calling Attack() on Boss object through pointer to Enemy:\n"; Enemy* pBadGuy = new Boss(); pBadGuy->Attack(); cout << "\n\nDeleting pointer to Enemy:\n"; delete pBadGuy; pBadGuy = NULL; return 0; } A potential problem exists when you use a pointer to a base class to point to an object of a derived class. When you delete the pointer, only the base class’ destructor will be called for the object. This could lead to disastrous results because the derived class’ destructor might need to free memory (as the destructor for Boss does). The solution is to make the base class’ destructor virtual. That way, the derived class’ destructor is called, which (as always) leads to the calling the base class’ destructor, giving every class the chance to clean up after itself.

Looking at Poly Bad Guy // // main - it all begins here // int main() { cout << "Calling Attack() on Boss object through pointer to Enemy:\n"; Enemy* pBadGuy = new Boss(); pBadGuy->Attack(); cout << "\n\nDeleting pointer to Enemy:\n"; delete pBadGuy; pBadGuy = NULL; return 0; } A potential problem exists when you use a pointer to a base class to point to an object of a derived class. When you delete the pointer, only the base class’ destructor will be called for the object. (in this case Enemy is the base class) This could lead to disastrous results because the derived class’ destructor might need to free memory (as the destructor for Boss does). The solution is to make the base class’ destructor virtual. That way, the derived class’ destructor is called, which (as always) leads to the calling the base class’ destructor, giving every class the chance to clean up after itself.

Looking at Poly Bad Guy // // main - it all begins here // int main() { cout << "Calling Attack() on Boss object through pointer to Enemy:\n"; Enemy* pBadGuy = new Boss(); pBadGuy->Attack(); cout << "\n\nDeleting pointer to Enemy:\n"; delete pBadGuy; pBadGuy = NULL; return 0; } A potential problem exists when you use a pointer to a base class to point to an object of a derived class. When you delete the pointer, only the base class’ destructor will be called for the object. This could lead to disastrous results because the derived class’ destructor might need to free memory (as the destructor for Boss does). The solution is to make the base class’ destructor virtual. That way, the derived class’ destructor is called, which (as always) leads to the calling the base class’ destructor, giving every class the chance to clean up after itself. class Enemy { public: Enemy(int damage = 10); virtual ~Enemy(); void virtual Attack() const; protected: int* mp_Damage; };

Looking at Poly Bad Guy // // main - it all begins here // int main() { cout << "Calling Attack() on Boss object through pointer to Enemy:\n"; Enemy* pBadGuy = new Boss(); pBadGuy->Attack(); cout << "\n\nDeleting pointer to Enemy:\n"; delete pBadGuy; pBadGuy = NULL; return 0; } A potential problem exists when you use a pointer to a base class to point to an object of a derived class. When you delete the pointer, only the base class’ destructor will be called for the object. This could lead to disastrous results because the derived class’ destructor might need to free memory (as the destructor for Boss does). The solution is to make the base class’ destructor virtual. That way, the derived class’ destructor is called, which leads to the calling of the base class’ destructor, giving every class the chance to clean up after itself.

Independent Activity: Poly Bad Guy On your own – To see what the keyword virtual ‘really’ does: Take the previous program Remove the keyword virtual from everywhere it appears See what changes

Independent Activity: Pure Virtual On your own – Abstract Class – Pure Virtual Functions – Download and play with EX074_AbstractCreature.cpp

Marker Slide Any questions on: – UML Hierarchy (review) – C++ Inheritance (review) – Inheritance (new) Simple Boss Overriding Boss – Polymorphism (new) Polymorphic Bad Guy Next up – Program Design Blackjack Game

Standard game of Blackjack – also called 21 Object – Obtain the set of cards closest to 21 without going over

Blackjack Game Classes Useful C++ classes to have around for the game

Classes: Inheritance Relations Generic player is shaded to indicate it is an abstract class – i.e. all virtual functions, base class only, – not intended to be instantiated

Classes: More Details Cards: – real-life cards – don’t copy when you deal it from he deck, move it to a hand – allocate them on the heap (free store) Hand – vector of pointers to Card objects – cards moving from hand to hand are really pointers that are being copied and destroyed

Classes: More Details Players – Humans and Computer – Each really is a “Hand” – Computer will be the dealer (aka House) which has unique rules to determine “hit” or “stay” – Humans will be players requires human input for “hit” or “stay” Deck – Similar to a hand – Starts as all 52 cards (randomly ordered) – Needs to be able to “deal” cards to player and the house objects

Card Class

Hand Class

GenericPlayer (abstract) Class

Player Class

House Class

Deck Class

Game Class

Game Flow Deal players and the house 2 initial cards Hide the house’s first card (facedown) Display players’ and house’s hands Deal additional cards to players Reveal House’s first card Deal additional cards to house If House busted – Everyone who is not busted wins Else – Each non-busted player above house’s total wins – Players with total over 21, or less than equal to house lose

main() function of Blackjack Game int main() { cout << "\t\tWelcome to Blackjack!\n\n"; int numPlayers = 0; while (numPlayers 7) { cout << "How many players? (1 - 7): "; cin >> numPlayers; } vector names; string name; for (int i = 0; i < numPlayers; ++i) { cout << "Enter player name: "; cin >> name; names.push_back(name); } cout << endl; // the game loop Game aGame(names); char again = 'y'; while (again != 'n' && again != 'N') { aGame.Play(); cout << "\nDo you want to play again? (Y/N): "; cin >> again; } return 0; }

Marker Slide Any Questions on: Any questions on: – UML Hierarchy (review) – C++ Inheritance (review) – Inheritance (new) Simple Boss Overriding Boss – Polymorphism (new) Polymorphic Bad Guy – Program Design Blackjack Game Next up – Free Play --- and an in-class assignment

Graded In-Class Activity: Blackjack Implement and run a Blackjack program based on the design just discussed – Starter code (and one possible solution) is on D2L Download the file: – ICA020_broken_Blackjack.cpp Rename it: Blackjack.cpp Fix the program as indicated – Put your name and today’s date in the lead comments – Compile it – Run it – When satisfied with it (or class ends) upload the resulting FIXED code to the appropriate D2L dropbox You can work in groups – BUT each individual must submit something to D2L You may create a set of source files and possibly a makefile to solve this problem, but it is not required

Free Play – Things to Work On Graded In-Class Activity: Homework 4 Homework 5 Various In-Class Activities to revisit

The End Or is it?