![Page 1: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/1.jpg)
Beginning C++ Through Game Programming,
Second Edition by Michael Dawson
![Page 2: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/2.jpg)
Chapter 10
Inheritance and Polymorphism: Blackjack
![Page 3: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/3.jpg)
Objectives• Derive one class from another• Use inherited data members and member functions• Override base class member functions• Define virtual functions to enable polymorphism• Declare pure virtual functions to define abstract classes
![Page 4: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/4.jpg)
Inheritance• A key element of OOP is inheritance• Allows you to derive a new class from an existing one • New class automatically inherits data members and member functions of an existing class• Especially useful when you want to create a more specialized version of an existing class
![Page 5: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/5.jpg)
Inheritance Example
• Boss inherits Attack() and m_Damage from Enemy while defining SpecialAttack() and m_DamageMultiplier
![Page 6: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/6.jpg)
Base Classclass Enemy{public: int m_Damage;
Enemy(); void Attack() const;};
Enemy::Enemy(): m_Damage(10){}
void Enemy::Attack() const{ cout << "Attack inflicts " << m_Damage << " damage points!\n";
}
![Page 7: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/7.jpg)
Derived Classclass Boss : public Enemy{public: int m_DamageMultiplier; Boss(); void SpecialAttack() const;
};
Boss::Boss(): m_DamageMultiplier(3){}
void Boss::SpecialAttack() const{ cout << "Special Attack inflicts " << (m_DamageMultiplier * m_Damage); cout << " damage points!\n";}
![Page 8: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/8.jpg)
Deriving a New Class
class Boss : public Enemy
• Boss is based on Enemy• Enemy is the base class (or superclass)• Boss is the derived class (or subclass) • Boss inherits Enemy’s data members and member functions, subject to access controls• Boss inherits and can directly access m_Damage and Attack()
![Page 9: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/9.jpg)
Using Objects of Derived Classes
• Enemy objects have Attack() member function but not SpeicalAttack() member function Enemy enemy1; enemy1.Attack();
• Boss objects have both Attack() and SpeicalAttack() member functions Boss boss1; boss1.Attack(); boss1.SpecialAttack();
![Page 10: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/10.jpg)
Member Functions Not Inherited
• Constructors• Copy constructors• Destructors• Overloaded assignment operators• Must write your own versions of these in the derived class
![Page 11: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/11.jpg)
Controlling Access under Inheritance
• When you derive one class from another, you can control how much access the derived class has to the base class’ members
• Generally want to provide only as much access as is necessary to a base class’ members in a derived class• Use access modifiers public, protected, and private
![Page 12: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/12.jpg)
Access Modifiers with Class Members
• public members are accessible to all code in a program• protected members are accessible only in their own class and certain derived classes, depending upon the access level used in
inheritance• private members are only accessible in their own class, which means they are not directly accessible in any kind of derived class
![Page 13: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/13.jpg)
Access Modifiers When Deriving Classes
• Use an access modifier when deriving a classclass Boss : public Enemy
• public derivation – public members in the base class become public members in the derived class – protected members in the base class become protected members in the derived class – private members are inaccessible
• Can derive a new class with the protected and private keywords, but they’re rarely used
![Page 14: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/14.jpg)
Calling and Overriding Base Class Member Functions
• Can customize how inherited member functions work in derived class• Can override them by giving them new definitions in derived class• Can explicitly call a base class member function from any member function of your derived class
![Page 15: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/15.jpg)
Base Classclass Enemy{public: Enemy(int damage = 10); void virtual Taunt() const; void virtual Attack() const;
private: int m_Damage;};
![Page 16: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/16.jpg)
Base Class (cont.)Enemy::Enemy(int damage): m_Damage(damage){}
void Enemy::Taunt() const{ cout << "The enemy says he will fight you.\
n";}
void Enemy::Attack() const{ cout << "Attack! Inflicts " << m_Damage << "
damage points.";}
![Page 17: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/17.jpg)
Derived Class
class Boss : public Enemy{public: Boss(int damage = 30); void virtual Taunt() const; void virtual Attack() const;};
![Page 18: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/18.jpg)
Derived Class (cont.)
Boss::Boss(int damage): Enemy(damage) //call base constructor {}
void Boss::Taunt() const //override base { cout << "The boss says he will end your
pitiful existence.\n";}
void Boss::Attack() const //override base { Enemy::Attack(); //call base cout << " And laughs heartily at you.\n";}
![Page 19: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/19.jpg)
Calling Base Class Constructors
• Can also explicitly call a base class constructor from a derived class constructor• Do this in the Boss constructor, which says to explicitly call the Enemy constructor and pass it damage Boss(int damage = 30):
Enemy(damage) • Pass the Enemy constructor the value that gets assigned to m_Damage
![Page 20: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/20.jpg)
Overriding Base Class Member Functions
• Can override a base class member function in derived class• Give new definition by defining the function in derived class• Boss Taunt() overrides Enemy Taunt()• New definition is executed when calling the member function through Boss object
![Page 21: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/21.jpg)
Overriding Base Class Member Functions: Tips
• Overriding member functions is useful when you want to change or extend the behavior of base class member functions in derived classes
• If you override an overloaded member function, it’s a good idea to override every version of the overloaded function
![Page 22: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/22.jpg)
Calling Base Class Member Functions
• Can directly call a base class member function in a derived class • Prefix class name to member function name with the scope resolution operator • Boss Attack() overrides Enemy Attack()• Enemy::Attack(); explicitly calls the Attack() member function of Enemy
![Page 23: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/23.jpg)
Overloaded Assignment Operator in a Derived Class
• Overloaded assignment operator isn't inherited from a base class• For overloaded assignment operator in a derived class, usually call
assignment operator member function from the base class
![Page 24: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/24.jpg)
Overloaded Assignment Operator in a Derived Class:
Example• Boss derived from Enemy, overloaded assignment operator member function defined in Boss could start as follows:
Boss& operator=(const Boss& b){ //handles data members inherited from Enemy Enemy::operator=(b); //now take care of data members in Boss
• Explicit call to Enemy assignment operator member function handles the data members inherited from Enemy • Rest of the member function would take care of the data members defined in Boss
![Page 25: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/25.jpg)
Copy Constructor in a Derived Class
• Copy constructor isn't inherited from a base class• For copy constructor in derived class, usually want to call the copy constructor
from a base class
![Page 26: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/26.jpg)
Copy Constructor in a Derived Class: Example
• If Boss is derived from Enemy, the copy constructor defined in Boss could start as follows:
//handles data members inherited from EnemyBoss (const Boss& b): Enemy(b){ //take care of data members defined in Boss
• Calling Enemy copy constructor with Enemy(b) copies Enemy object's data members into the new Boss object • In remainder of Boss copy constructor, take care of copying the data members declared in Boss for the new object
![Page 27: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/27.jpg)
Polymorphism
• One of the pillars of OOP• Member function will produce different results depending on the type of object for which it is being called • Example:
– A group of bad guys is made of objects of different types that are related through inheritance, such as enemies and bosses– You call the same member function for each bad guy in the group,like Attack(), and each object would determine the exact effects– Effect of the function calls is dynamic and is determined at runtime, depending on the object type
![Page 28: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/28.jpg)
Pointers to Objects of Base Class
• An object of a derived class is also a member of the base class• Can use a pointer to the base class to point to an object of the derived class• Assuming Boss is derived from Enemy: Enemy* pBadGuy = new Boss();
• Allows you to deal with objects without knowing their exact type
![Page 29: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/29.jpg)
Virtual Member Functions
• Virtual member functions allow for polymorphic behavior
• If VTaunt() is defined as virtual in Enemy and overridden in Boss, then pBadGuy->VTaunt();
• Executes Boss VTaunt() member function• If VTaunt() had not been virtual in Enemy,
then even if Boss had overridden the member function, Enemy VTaunt() would have been called through the Boss object
![Page 30: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/30.jpg)
Creating Virtual Member Function
• Add virtual before name function when you declare it• In Enemy void virtual VTaunt() const { cout << "The enemy says he will fight you.\n"; }
• VTaunt () is virtual in Enemy and it's inherited as a virtual function in Boss
![Page 31: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/31.jpg)
Creating Virtual Member Function (cont.)
• When you override VTaunt() in Boss with void virtual VTaunt() const { cout << "The boss says he will
end your pitiful existence.\n"; }
• The correct version of VTaunt() will be called (based on the type of object) and will not be fixed by the type of pointer
![Page 32: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/32.jpg)
Virtual Member Function: Tips
• Once a member function is defined as virtual, it’s virtual in any derived class• Don’t have to use the keyword virtual when you override a virtual member function in a derived class, but you should use it anyway because it will remind you that the function is indeed virtual• Virtual functions produce polymorphic behavior through references as well pointers• Benefits of virtual functions aren't free; there is a performance cost associated with the overhead.• Use virtual functions only when you need them • Once you’ve defined one virtual member function in a class, defining another in that class doesn’t cost you much more
![Page 33: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/33.jpg)
Slicing Objects
• Can use a pointer or reference to the base class to point to an object of the derived class• Assigning an object of a derived class to a variable of a base class slices the object, losing the data
members declared in the derived class and losing access to member functions of the derived class • Avoid slicing objects
![Page 34: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/34.jpg)
Virtual Destructors• When you use a pointer to a base class to point to an object of a derived class, you have a potential problem• When you delete the pointer, only the base class’ destructor will be called for the object • Solution is to make the base class’ destructor virtual • Then derived class’ destructor is called, which leads to base class’ destructor being called• Make a destructor virtual with virtual keyword virtual ~Enemy()
• Good rule of thumb: if you have any virtual member functions in a class, make the destructor virtual, too.
![Page 35: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/35.jpg)
Abstract Classes
• A class that can’t be used to instantiate an object
• A generic class upon which to base other classes
• Example: a generic Creature class upon which classes Pixie, Dragon, and Orc are based
• Doesn't make sense to instantiate Creature objects, but pixies, dragons, and orcs have common elements
• Creature would be an abstract class
![Page 36: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/36.jpg)
Pure Virtual Functions• A pure virtual function is one to which you don’t need to give a definition• Specify a pure virtual function by placing an equal sign and a zero at the end of the function header of a virtual function • In a Creature class, Greet() is a pure virtual function: virtual void Greet() const = 0;
• When a class contains at least one pure virtual function, it’s an abstract class• An abstract class can have data members and can have virtual functions that are not pure virtual
![Page 37: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/37.jpg)
Deriving a Class from an Abstract Class
• When you derive a new class from an abstract class, you can override its pure virtual functions• If you override all of its pure virtual functions, then the new class is not abstract; you can instantiate objects from it. • In an Orc class derived from Creature: virtual void Greet() const { cout << "The orc grunts hello.\n"; }
• Orc is not abstract, and objects can be instantiated from it
![Page 38: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/38.jpg)
Summary• Inheritance allows you to derive a new class from an existing one • A derived class automatically inherits data members and member functions from base class• A derived class does not inherit constructors, copy constructors, destructors, or an overloaded assignment operator• Base class constructors are automatically called before the derived class constructor when a derived class object is instantiated• Base class destructors are automatically called after the derived class destructor when a derived class object is destroyed
![Page 39: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/39.jpg)
Summary (cont.)• protected members are accessible only in their own class and certain derived classes, depending upon the derivation access level• Using public derivation means that public members in the base class become public members in the derived class, protected members in the base class become
protected members in the derived class, and private members are inaccessible• Can override base class member functions by giving them new definitions in a derived class• Can explicitly call a base class member function from a derived class• Can explicitly call the base class constructor from a derived class instructor
![Page 40: Beginning C++ Through Game Programming, Second Edition](https://reader036.vdocument.in/reader036/viewer/2022062301/56814e32550346895dbb98a6/html5/thumbnails/40.jpg)
Summary (cont.)• Polymorphism is the quality whereby a member function will produce different results depending on the type of object for which it is called • Virtual functions allow for polymorphic behavior • A pure virtual function is a function to which you don’t need to give a definition • An abstract class has at least one pure virtual member function• An abstract class can’t be used to instantiate an object