CS11 Introduction to C++ Fall Lecture 7

Similar documents
POLYMORPHISM 2 PART. Shared Interface. Discussions. Abstract Base Classes. Abstract Base Classes and Pure Virtual Methods EXAMPLE

POLYMORPHISM 2 PART Abstract Classes Static and Dynamic Casting Common Programming Errors

Inheritance, and Polymorphism.

OOPS Viva Questions. Object is termed as an instance of a class, and it has its own state, behavior and identity.

What is Polymorphism? Quotes from Deitel & Deitel s. Why polymorphism? How? How? Polymorphism Part 1

Polymorphism Part 1 1

(12-1) OOP: Polymorphism in C++ D & D Chapter 12. Instructor - Andrew S. O Fallon CptS 122 (April 3, 2019) Washington State University

CS32 - Week 4. Umut Oztok. Jul 15, Umut Oztok CS32 - Week 4

Polymorphism. Zimmer CSCI 330

What are the characteristics of Object Oriented programming language?

QUIZ. Write the following for the class Bar: Default constructor Constructor Copy-constructor Overloaded assignment oper. Is a destructor needed?

Data Structures (list, dictionary, tuples, sets, strings)

OBJECT ORIENTED PROGRAMMING USING C++ CSCI Object Oriented Analysis and Design By Manali Torpe

C++ Crash Kurs. Polymorphism. Dr. Dennis Pfisterer Institut für Telematik, Universität zu Lübeck

Chapter 12. OOP: Creating Object-Oriented Programs The McGraw-Hill Companies, Inc. All rights reserved. McGraw-Hill

Java Object Oriented Design. CSC207 Fall 2014

CS 162, Lecture 25: Exam II Review. 30 May 2018

Chapter 1: Object-Oriented Programming Using C++

Short Notes of CS201

CS201 - Introduction to Programming Glossary By

ECE 3574: Dynamic Polymorphism using Inheritance

CS313D: ADVANCED PROGRAMMING LANGUAGE

VIRTUAL FUNCTIONS Chapter 10

Chapter 5 Object-Oriented Programming

G Programming Languages - Fall 2012

Programming in C++ Prof. Partha Pratim Das Department of Computer Science and Engineering Indian Institute of Technology, Kharagpur

CS11 Introduction to C++ Fall Lecture 1

CS11 Advanced C++ Fall Lecture 3

Introduction to C++ Introduction to C++ Dr Alex Martin 2013 Slide 1

C++ Programming: Polymorphism

Fast Introduction to Object Oriented Programming and C++

the gamedesigninitiative at cornell university Lecture 7 C++ Overview

Note 12/1/ Review of Inheritance Practice: Please write down 10 most important facts you know about inheritance...

Overview of OOP. Dr. Zhang COSC 1436 Summer, /18/2017

CSE 303: Concepts and Tools for Software Development

Inheritance. OOP components. Another Example. Is a Vs Has a. Virtual Destructor rule. Virtual Functions 4/13/2017

Intro to OOP Visibility/protection levels and constructors Friend, convert constructor, destructor Operator overloading a<=b a.

CS105 C++ Lecture 7. More on Classes, Inheritance

C++ Important Questions with Answers

Programming II (CS300)

Object-Oriented Programming, Iouliia Skliarova

Contents. I. Classes, Superclasses, and Subclasses. Topic 04 - Inheritance

Modern C++ for Computer Vision and Image Processing. Igor Bogoslavskyi

CS250 Final Review Questions

Lecture Contents CS313D: ADVANCED PROGRAMMING LANGUAGE. What is Inheritance?

Inheritance CSC 123 Fall 2018 Howard Rosenthal

PROGRAMMING LANGUAGE 2

Object-Oriented Concept

04-24/26 Discussion Notes

Object Oriented Programming: Inheritance Polymorphism

Lecture 5: Inheritance

G52CPP C++ Programming Lecture 13

ITI Introduction to Computing II

Chapter 11. Categories of languages that support OOP: 1. OOP support is added to an existing language

CS11 Advanced C++ Fall Lecture 7

CPS 506 Comparative Programming Languages. Programming Language

Increases Program Structure which results in greater reliability. Polymorphism

Data Abstraction. Hwansoo Han

Absolute C++ Walter Savitch

Object-Oriented Programming (OOP) Fundamental Principles of OOP

CSC207H: Software Design. Java + OOP. CSC207 Winter 2018

Polymorphism. Miri Ben-Nissan (Kopel) Miri Kopel, Bar-Ilan University

G Programming Languages Spring 2010 Lecture 9. Robert Grimm, New York University

Programming Language Concepts Object-Oriented Programming. Janyl Jumadinova 28 February, 2017

Lecture 13: more class, C++ memory management

Inheritance and Polymorphism

Extending Classes (contd.) (Chapter 15) Questions:

Cpt S 122 Data Structures. Course Review Midterm Exam # 2

Inheritance: Develop solutions by abstracting real-world object and their interaction into code to develop software solutions. Layering: Organization

Basic Principles of OO. Example: Ice/Water Dispenser. Systems Thinking. Interfaces: Describing Behavior. People's Roles wrt Systems

Object Oriented Programming in Java. Jaanus Pöial, PhD Tallinn, Estonia

ITI Introduction to Computing II

Programming Exercise 14: Inheritance and Polymorphism

Introduction to Design Patterns

Inheritance. Inheritance Reserved word protected Reserved word super Overriding methods Class Hierarchies Reading for this lecture: L&L

OOPs Concepts. 1. Data Hiding 2. Encapsulation 3. Abstraction 4. Is-A Relationship 5. Method Signature 6. Polymorphism 7. Constructors 8.

C++ Review. CptS 223 Advanced Data Structures. Larry Holder School of Electrical Engineering and Computer Science Washington State University

CSC207H: Software Design. Java + OOP. CSC207 Winter 2018

Rules and syntax for inheritance. The boring stuff

Introduction to Programming Using Java (98-388)

CSC207 Week 3. Larry Zhang

Chapter 14 Abstract Classes and Interfaces

CSE 303 Lecture 23. Inheritance in C++ slides created by Marty Stepp

Lecture 14: more class, C++ streams

Abstract Classes and Interfaces

CS260 Intro to Java & Android 03.Java Language Basics

Reviewing for the Midterm Covers chapters 1 to 5, 7 to 9. Instructor: Scott Kristjanson CMPT 125/125 SFU Burnaby, Fall 2013

Homework 6. Yuji Shimojo CMSC 330. Instructor: Prof. Reginald Y. Haseltine

Comp 249 Programming Methodology

QUIZ on Ch.5. Why is it sometimes not a good idea to place the private part of the interface in a header file?

Today s lecture. CS 314 fall 01 C++ 1, page 1

Programming II (CS300)

Module 10 Inheritance, Virtual Functions, and Polymorphism

Lesson 10A OOP Fundamentals. By John B. Owen All rights reserved 2011, revised 2014

C++ Inheritance and Encapsulation

CS/ENGRD 2110 FALL Lecture 6: Consequence of type, casting; function equals

IT101. Inheritance, Encapsulation, Polymorphism and Constructors

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

CS313D: ADVANCED PROGRAMMING LANGUAGE

CPSC 427: Object-Oriented Programming

Transcription:

CS11 Introduction to C++ Fall 2012-2013 Lecture 7

Computer Strategy Game n Want to write a turn-based strategy game for the computer n Need different kinds of units for the game Different capabilities, strengths, weaknesses, etc. n Examples: Infantry unit Transport ship Trebuchet

Unit Classes n Infantry unit data members: Current location, strength, experience level Who owns the unit n Member functions: Move to another location Attack another unit, receive attack from another unit n What about transport ships? Probably not experience level or attack a unit Need to add a list of things the ship is carrying n Trebuchets are very similar to infantry units Just a different way of attacking other units

Common Themes n Very clear we have common themes here! All units have a location, strength, owner All units can move around All units can be attacked n Also have specialized capabilities Infantry units and trebuchets can t carry other stuff, and they can t make it very far on water Of course, boats can t make it very far on land

Single-Class Implementation n Doesn t make sense to put all features in one class class GameUnit { UnitType type; Point location; int playerid; int strength; // For transport ships only! int transportcapacity; vector<gameunit *> contents; public:... bool move(const Map &map, int direction); // For infantry and trebuchets only! bool attack(const Map &map, int direction); // For transport ships only! bool transportitem(gameunit *u); };

Single-Class Implementation (2) n Not a clean abstraction! Both data and operations for infantry units are mixed together with transport ships, etc. Hard to understand what is going on n Very likely to lead to bugs, e.g. Infantry units can accidentally carry other units Transport ships can attack other units n Also wastes space Infantry unit doesn t need list of units it s carrying

C++ Class Inheritance n C++ provides class inheritance (as do all OOP languages) n Base class provides generalized capabilities A game unit type with location and owner Basic ability to move unit around, retrieve owner info, etc. n Derived classes inherit the state and behavior of the base class They can also move around or report the unit s owner n Derived classes also provide specialized capabilities The transport ship type adds the ability to hold other units The trebuchet type adds the capability to rain fiery death from above

Class Inheritance (2) n Class inheritance models an is-a relationship An infantry unit is a game unit A transport ship is a game unit A trebuchet is a game unit n Terminology: Base class, parent class, superclass Derived class, child class, subclass

A Game Unit Base-Class class GameUnit { Point location; int playerid; int strength; public: GameUnit(const Point &loc, int owner, int strength); Point getlocation() const; bool move(const Map &map, int direction); string getunittype() const { return "generic game unit"; } }; n Basic features common to all game units

Extending the Generic Game Unit n Transport Ship class will extend GameUnit Add in new state and behaviors class TransportShip : public GameUnit { int capacity; vector<gameunit *> contents; public: TransportShip( /* TODO */ ); bool loadunit(gameunit *u); vector<gameunit *> unloadall(); }; Don t need to specify location, owner, etc. n State and associated behaviors inherited from parent class Can also provide new capabilities n Ability to load and unload units from the transport

Generic Functions n This class can use GameUnit type for its functions class TransportShip : public GameUnit { int capacity; vector<gameunit *> contents; public: TransportShip( /* TODO */ ); bool loadunit(gameunit *u); vector<gameunit *> unloadall(); }; Because any subclass of GameUnit is a GameUnit, we can pass any subclass to our load/unload functions Don t need to provide a version for each specific subclass! n Same general principle for other APIs! Write functions against the base-type where appropriate

Transport-Ship Constructor n Need to implement the transport ship constructor Problem: base class also has its own data members We need to initialize these members too n First attempt: TransportShip(const Point &loc, int owner, int capacity) : location(loc), playerid(owner), strength(100), capacity(capacity) { assert(capacity > 0); } Doesn t compile! Subclasses cannot initialize base-class data members directly.

Calling Base-Class Constructor n Want to call the base-class constructor from the subclass constructor Must call the base-class constructor in member initializer list Must be the first item of the member initializer list! n Transport ship constructor, take 2: TransportShip(const Point &loc, int owner, int capacity) : GameUnit(loc,owner,100),capacity(capacity) { assert(capacity > 0); } Now we get to reuse our GameUnit constructor code!

Initialization of Derived Classes n Remember the class initialization process: All (non-primitive) data members of a class are initialized before the class constructor-body is run Constructor-body can refer to these members, because they have already been initialized n Same is true for class hierarchies Base-class initialization occurs before derivedclass initialization Derived class constructor body can also refer to data members in the base class!

Initialization of Derived Classes (2) n Initialization of base-class members normally happens automatically Base class default constructor is called before the derived class is initialized Don t need to put this in the member initializer list; it happens automatically! n But, not every base class has a default constructor! or, you may simply not want the default initialization n In these cases, need to put the non-default baseclass constructor call in the member initializer list and it needs to be first in the initializer list.

Transport Ship s Unit-Type n GameUnit class has getunittype() function Returns generic game unit n Would like our Transport Ship class to say that it s a transport ship n TransportShip class can override the function s implementation string TransportShip::getUnitType() const { return "transport ship"; } n Derived classes can override a base-class function Replace the implementation completely, or specialize its behavior in some way

Overriding Base-Class Functions n When overriding a function, function signature in derived class must match base class signature string getunittype() const If signatures don t match, C++ thinks you are simply adding a new function to the derived class

Calling Our Function n Try out our new unit-type function GameUnit u(point(20, 30), 1, 100); TransportShip s(point(30, 40), 1, 4); cout << "I am a " << u.getunittype() << endl; cout << "I am a " << s.getunittype() << endl; Prints out: I am a generic game unit I am a transport ship

Display Helper-Function n Now we decide to write a helper function: void display(const GameUnit &u) { cout << "I am a " << u.getunittype() << endl; } GameUnit u(point(20, 30), 1, 100); TransportShip s(point(30, 40), 1, 4); display(u); display(s); Prints out: I am a generic game unit I am a generic game unit

Yay, Another Fun C++ Pitfall! n By default, C++ uses the variable s type to figure out which function to call The type specified in the source code, and known at compile-time Called the variable s static type n Code: void display(const GameUnit &u) { cout << "I am a " << u.getunittype() << endl; } Static type of u is GameUnit, so C++ always calls GameUnit::getUnitType() even when u refers to a subclass of GameUnit

Virtual Functions n The virtual keyword tells C++ to call the member function based on what is referred to, not on the static type of the variable Called the runtime type of the variable n In GameUnit class declaration, update the getunittype() declaration: n virtual string getunittype() const {... } TransportShip doesn t need to re-specify virtual when it overrides getunittype() n The function s virtual-ness is also inherited If TransportShip added its own new functions, and wanted its subclasses to override them: n Have to specify virtual on the new function declarations

Virtual Function Mechanics n Why not make all functions virtual? Need to understand how C++ implements virtual functions n Declaring a function virtual causes C++ to store an extra pointer to correct version of the function Stored in a virtual function pointer table n The object itself knows which function to call location owner (20, 30) 1 GameUnit getunittype() GameUnit::getUnitType() location owner (30, 40) 1 Transport Ship getunittype() TransportShip::getUnitType() capacity contents 4 { }

Virtual Function Mechanics (2) n Two-step process for calling virtual functions: Look up which version of the function to call, using the object itself Go ahead and call that function n Two costs of virtual functions: To support virtual functions, objects require an extra pointer s worth of space n If you need many objects of a particular type in memory at the same time, need to avoid virtual functions! Virtual function calls also incur a (small) time overhead n For extremely performance-critical applications, may also want to avoid virtual functions due to this overhead n Only declare functions virtual when you expect them to be overridden

Destructors? n One more fun test: GameUnit *u1 = new GameUnit(p1, 1, 100); GameUnit *u2 = new TransportShip(p2, 1, 4);... delete u1; delete u2; Which destructors are called? n Both delete operations call the GameUnit destructor! L

Virtual Destructors n Base classes also need a virtual destructor Probably the most important thing to do right, when it comes to class hierarchies n C++ standard specifies that: Deleting a derived class through a base-class pointer, with a non-virtual destructor, results in undefined behavior Normally, you just leak memory, because the object isn t entirely cleaned up n When you intend a class to be subclassed, always give it a virtual destructor Conversely, if you don t want a class to be subclassed, don t give it a virtual destructor

Virtual Destructors (2) n When specifying a virtual destructor, make sure to give the destructor a body Even when the destructor doesn t do anything! Not specifying a body for the destructor will produce linker errors at compile-time n Updating our GameUnit class: class GameUnit {... // Give GameUnit a virtual destructor, // since we intend it to be subclassed. virtual ~GameUnit() { } }; GameUnit class doesn t manage any dynamic resources

Calling Base-Class Functions n n n When overriding a base-class function, a subclass may simply want to alter the base-class behavior Example: transport ship also needs to move But, it needs to stay in the water Override GameUnit::move() Add in extra test to ensure the ship stays in the water Then, call GameUnit s version of move() bool TransportShip::move(const Map &map, int direction) { Point nextloc = location.neighbor(direction); if (map.celltype(nextloc) == WATER) // Reuse base-class implementation. return GameUnit::move(map, direction); else return false; }

Private Member-Variables n GameUnit is declared like this: class GameUnit { Point location; int playerid;... What access-level are these data members? private is default access-level for classes. n Can TransportShip actually do this? bool TransportShip::move(const Map &map, int direction) { Point nextloc = location.neighbor(direction);... No! Only the class itself can access its private members. Produces a compiler-error.

The protected Access-Modifier n To make base-class members accessible to subclasses, use protected access-modifier n Change GameUnit declaration to: class GameUnit { protected: // Make accessible to subclasses! Point location; int playerid;... n Now TransportShip can access GameUnit variables without compiler errors bool TransportShip::move(const Map &map, int direction) { Point nextloc = location.neighbor(direction);...

private or protected? n When to use private? When protected? n No hard-and-fast rule. Opinions vary! n Some suggestions: In general, make parent-class members private, until you discover the need to manipulate them from the child class. Then make them protected. If parent class manages complicated structures, definitely make those things private. Instead, make protected functions for child classes to use. Similarly, if changes to variables need to be tightly controlled (e.g. for auditing or correctness reasons), make them private.

Abstract Functions n Some base classes just declare behavior, but don t define it Concept represented by base class is too general to be able to define any reasonable behavior Base class is intended to be extended n The base class defines abstract functions Base class can t be instantiated or used directly n Some of the class behavior hasn t been defined! Subclasses provide the implementation Subclasses are instantiated and used

Pure-Virtual Functions n n n n Functions are declared abstract by making them pure virtual Example: // Generic build task. class Task {... virtual bool run() = 0; // pure virtual }; // Task that compiles source code. class CompileTask : public Task {... virtual bool run() {... /* compile */ } }; run() is not defined in Task, only declared. Subclasses can provide their own definitions of run()

Pure-Virtual Functions n Trying to instantiate Task gives a compiler error Task *pt = new Task(); COMPILE ERROR n Can still have variables of type Task& or Task* Task *pt = new CompileTask(conf); OK! CompileTask has all Task members n Especially useful when providing generic processing capabilities for a variety of specialized objects void runalltasks(vector<task*> tasks); runalltasks can use the generic Task interface Each task-object provides its own implementation of Task::run()

Using Pure-Virtual Functions n Some base-classes have some pure-virtual functions The base-class provides some implementation The subclass provides the missing pieces n An interface is a base class with all pure-virtual functions The base class is only declaring behavior, but provides no implementation at all This concept of an interface is more explicit in other languages Note: must still provide virtual (not pure-virtual) destructor implementation, to correctly support object deletion!

The OOP Concepts (again) n So far, we have seen: Encapsulation: hiding and guarding internal state Abstraction: presenting a simple, high-level interface n Class hierarchies introduce two more: Inheritance: a child class gets its parent class members/ behavior n and a child-class can customize parent-class behavior Polymorphism: calling a function on an object can exhibit different behaviors, based on the object s type n In C++, this requires the use of virtual functions

This Week s Lab n Homework should be pretty straightforward Lots of class-inheritance stuff! n Complete the implementation of a simple algebra program > a = 5 > b = 2 * (a + 6) = 22 Represent expressions with an Abstract Syntax Tree (AST) Implement functionality to evaluate expressions 2 * + a 6