1 / 40

Beginning C++ Through Game Programming, Second Edition

Beginning C++ Through Game Programming, Second Edition. by Michael Dawson. Chapter 10. Inheritance and Polymorphism: Blackjack. Objectives. Derive one class from another Use inherited data members and member functions Override base class member functions

shubha
Télécharger la présentation

Beginning C++ Through Game Programming, Second Edition

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Beginning C++ Through Game Programming, Second Edition by Michael Dawson

  2. Chapter 10 • Inheritance and Polymorphism: Blackjack

  3. 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

  4. 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

  5. Inheritance Example • Boss inherits Attack() and m_Damage from Enemy while defining SpecialAttack() and m_DamageMultiplier

  6. Base Class • class 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"; • }

  7. Derived Class • class 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"; • }

  8. 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()

  9. 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();

  10. Member Functions Not Inherited • Constructors • Copy constructors • Destructors • Overloaded assignment operators • Must write your own versions of these in the derived class

  11. 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

  12. 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

  13. Access Modifiers When Deriving Classes • Use an access modifier when deriving a class • class 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

  14. 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

  15. Base Class • class Enemy • { • public: • Enemy(int damage = 10); • void virtual Taunt() const; • void virtual Attack() const; • private: • int m_Damage; • };

  16. 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."; • }

  17. Derived Class • class Boss : public Enemy • { • public: • Boss(int damage = 30); • void virtual Taunt() const; • void virtual Attack() const; • };

  18. 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"; • }

  19. 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

  20. 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

  21. 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

  22. 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

  23. 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

  24. 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

  25. 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

  26. 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 Enemy • Boss (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

  27. 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

  28. 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

  29. 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

  30. 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

  31. 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

  32. 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

  33. 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

  34. 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.

  35. 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

  36. 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

  37. 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

  38. 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

  39. 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

  40. 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

More Related