copyright © 1998-2014 curt hill inheritance in c++ how to do it

47
Copyright © 1998-2014 Curt Hill Inheritance in C++ How to do it

Upload: oswin-gaines

Post on 13-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Copyright © 1998-2014 Curt Hill

Inheritance in C++

How to do it

Copyright © 1998-2014 Curt Hill

Very little new Syntax

• In the header– Ancestral class– Specify the type of derivation– Give the new properties and methods– Virtual methods

• In the class code– Constructors– Ancestral method calls

• How used in client code

Copyright © 1998-2014 Curt Hill

Terminology– Derive

• To make a new class which inherits properties and methods from an older class

– Ancestor• The older class which defines the

inherited properties and methods• Also known as the base class or super

class

– Method• Member function

– Property• Member data

Copyright © 1998-2014 Curt Hill

Declaring a derived class• Normal class syntax is:

class name {– Name is the name of the new class

• Derivation syntax:class name : [visibility] ancestor {– Name is the new class name– Ancestor is the ancestral class name– Visibility is one of the three visibilities– Public is usually best, default is

private

Copyright © 1998-2014 Curt Hill

Notes

• The ancestral class must be accessible via an include– It may also be a derived class

• The visibility type is most frequently public– Other visibilities will be considered

later

Copyright © 1998-2014 Curt Hill

Example:– class student: public person { protected: int hours; college_type college; public: student (); student (char nme[], char m_or_f, date& d,int h=0, char c = 'u'); void set_college(char c); void incr_hours(int h); virtual void ToString(char *)const; }; // student class

Notes

• Every property and method of person now exists in student

• The visibility is not changed• Protected and public properties

and methods may be accessed by student code

Copyright © 1998-2014 Curt Hill

Copyright © 1998-2014 Curt Hill

Adding properties and methods

• Protected is only of importance in derivations– Allows a derived class to access but not

client

• Any methods given may either be new or override an existing method– They augment existing methods

• Properties add to existing properties• The virtual is optional in all but the base

class– Good documentation

Copyright © 1998-2014 Curt Hill

Override

• To override is to create a new method with the same signature as an inherited method

• The override method will be executed and not the overridden– Regardless of where the call occurs

Copyright © 1998-2014 Curt Hill

Removing• There is no remove syntax

– There are tricks

• Restricted derivations reduce everything of a visibility to a lower visibility

• Most properties are hidden from client so that is not a problem

• Methods:– Change the visibility from public to

protected or private• Now inaccessible

– Override to do nothing or error

Copyright © 1998-2014 Curt Hill

Polymorphism

• Objects in the same inheritance tree are interchangable– Any may be called

• Choosing the correct function based on the object at run-time– Dynamic binding – Only possible with pointers– Pointer type must be an ancestral

type

Copyright © 1998-2014 Curt Hill

Binding• Earlier programming languages

used static binding only– At compile or link time determine the

function needed– Examples: Pascal, C, COBOL

• Some programming languages use dynamic binding only– Determine function needed at run time– Examples: LISP and Java

• C++ uses both, depending on situation

Copyright © 1998-2014 Curt Hill

C++ Binding• Stroustrup was walking a fine line

in the design of C++• He wanted the efficiency of C and

the OO power of Smalltalk• Thus he puts in the hands of the

programmer whether the method is polymorphic, that is has dynamic binding

• This is done with presence of virtual keyword

Interchangeability• Polymorphism makes types

interchangeable– These classes have an “is a”

relationship

• A cast converts a value from one type to another

• Interchangeability means to accept that value without cast or other change

• Upcasting is an exampleCopyright © 1998-2014 Curt Hill

Upcasting

• To upcast is to treat an object lower on the inheritance tree as if it were higher– To treat a derived class like one of its

super classes

• It is easy – not actually a cast at all• The storage of the ancestor always

precedes that of the descendent• See the pictures in next two slides

Copyright © 1998-2014 Curt Hill

Example Hierarchy

Copyright © 1998-2014 Curt Hill

person

employee student

grad

name

wage hours

degree

Storage of Grad

Copyright © 1998-2014 Curt Hill

Name

Hours

Degree

Person properties

Student properties

Grad properties

The IBM 360 Floating Point Trick

Copyright © 1998-2014 Curt Hill

C++ Requirements for Polymorphism

• The object must be referenced by a pointer– Pointers are always same length

• The pointer type must be a pointer to the base type

• The function called must be declared virtual in the base type

• All the sub-classes have the function with the same signature

Copyright © 1998-2014 Curt Hill

Polymorphism

• Is enabled by Virtual functions• Any ancestral method that is prefixed

by virtual forces all descendent functions with same signature to also be virtual

• The polymorphism is only demonstrated when a pointer is used.– Pointer must be to ancestral class

• Stack items are of different sizes so are not interchangeable– Unlike pointers

Copyright © 1998-2014 Curt Hill

Polymorphic Non-Example

• Student s, * sptr;Person p, *pptr;st = s.ToString();– This is not polymorphic since we

know exactly what the type of s is.

• sptr->set_name(“Bill Smith”);– This is not polymorphic since

set_name is only defined in Person

Copyright © 1998-2014 Curt Hill

Polymorphic Example

• Person * p;p = new student(…);p = new person(…);// Assignment of any // descendent is legalst = p->ToString();– This is polymorphic since we do not

know whether p is a pointer to a person or any of its descendents

– Run-time system must figure it out for us

Copyright © 1998-2014 Curt Hill

Consider – class X {

void A(){ … B(); …} virtual void B() {…} }; // end of X

– class Y:public X { virtual void B() {…} }; // end of Y

– X * u; Y * v;u->A(); // Calls X.A and then X.Bv->A(); // Calls X.A and then Y.B

– A descendent B is called by an ancestral A

Copyright © 1998-2014 Curt Hill

Constructors

• The idea is that we build the class values when it is created

• There are two related problems having to do with default constructors– Constructing a derived class must

also construct the ancestral– When the constructor starts any

contained classes are already made

Copyright © 1998-2014 Curt Hill

Problem example

• Suppose:class person { protected: date birth; char name[20];…

• Date is a class– It must have a default constructor

Copyright © 1998-2014 Curt Hill

The Person Constructor• Person::person(…){

birth = date(1,2,87);• When the constructor starts (following

the {)• All the contained or ancestral things

have already been constructed• Two problems:

– Default constructor may not be accessible– Wasteful - Default construction plus second

construction

Copyright © 1998-2014 Curt Hill

The solution

• A different notation for construction• Person::person(int m,int d, int y):

birth(m,d,y),name(“Bill Smith”){}• Property names are treated like

functions and initial value is put in them– Even if not a class name– These are executed before any property

construction and before anything in braces

Copyright © 1998-2014 Curt Hill

Same notation for inheritance

• In inheritance the ancestral class name is treated like a variable

• Thus a non-default constructor may be called

• Most things in the initialization list are member data names except the ancestral class

• Example follows

Copyright © 1998-2014 Curt Hill

Example: Student constructor

• student::student(char nme[], char m_or_f, date & d, int h,char c) : person(nme,m_or_f,d), hours(h) { set_college(c);}

Copyright © 1998-2014 Curt Hill

Summary for Construction

• In inheritance the ancestral class name is treated like a variable– Thus a non-default constructor may

be called

• All variable names are treated like functions

• Initialization list is completed before the body of the constructor is executed– Often the body is empty

Copyright © 1998-2014 Curt Hill

Pure Virtual Functions

• Used to define interface• No implementation• The header is assigned zero:virtual int s1(int i)const=0;virtual int s2()=0;

Copyright © 1998-2014 Curt Hill

Abstract Base Classes

• Contain one or more pure virtual functions– Either their own or inherited from a super

class

• Cannot be instantiated• Any descendent must implement all

pure virtual functions to be instantiable• May have a pointer of that type, which

is used for polymorphism for the whole tree

• May not implement = operator

Copyright © 1998-2014 Curt Hill

Example• class shape {

double x,y; public: virtual void move(double dx, double dy); virtual void draw() = 0;… };class circle: public shape{ void draw(); … };…shape * sp;

Copyright © 1998-2014 Curt Hill

Example explained

• Shape is an abstract class• Circle’s draw overrides shape’s

draw – Circle may be instantiated

• Even though shape cannot be instantiated a pointer that will contain several shapes may have that type

Copyright © 1998-2014 Curt Hill

Accessing Overridden Methods

• When a descendent overrides an existing method the method is still available

• The ancestral name and scope resolution operator are used

• Consider following example

Copyright © 1998-2014 Curt Hill

Example 1class anc{

...

int meth(int a);}; // end of anc

class desc: public anc{ ... int meth(int a);}; // end of desc

int desc::meth(int a){ ... c = anc::meth(a); ...}

Example 2• Consider the ToString of the

Student class• It should not re-implement the

ToString of Person– It should just call it

• Such as:wxString student::ToString(){ wxString s = Person::ToString(); s = s << “ “ << hours; …

Copyright © 1998-2014 Curt Hill

Copyright © 1998-2014 Curt Hill

Visibility Again

• There are two ways to modify visibilities of the base class

• Individual methods may be altered by overriding them– Override at a different visibility– Can be done if base class made

something other than private

• All visibilities may be lowered by using derivation visibility

Copyright © 1998-2014 Curt Hill

Exampleclass anc{

protected:

int meth1(int a); int meth2(int a);}; // end of anc

class desc: public anc{ private: int meth1(int a); public: int meth2(int a);}; // end of desc

Copyright © 1998-2014 Curt Hill

Derivation Visibility

• The visibility given in the class header determines the visibility of the items from the superclass in this class

• This can reduce visibility but never make it more visible

• Public derivations preserve the existing visibilities

Copyright © 1998-2014 Curt Hill

New VisibilitiesDerivation type / Base class visibility / Result visibility

Was Public

Was Protected

Was Private

Public Public Protected Private

Protected Protected Protected Private

private Private Private Private

Copyright © 1998-2014 Curt Hill

Other Derivations

• Protected visibility– Hides all methods and properties

from clients– Preserves access to this and sub

classes

• Private visibility– Hides all methods and properties

from clients and sub classes– Similar to composition where

ancestral class is now private

Copyright © 1998-2014 Curt Hill

Multiple Inheritance

• Recall the grad class– It inherited behavior from both

student and person

• Multiple inheritance is the inheriting of behavior from two different classes– These classes are not usually in the

same inheritance tree

Copyright © 1998-2014 Curt Hill

Syntax

• Just about what you expect• class C: public A, public B {• The C class inherits all the

properties and methods of both A and B

• Class C is interchangeable with both A and B classes

Copyright © 1998-2014 Curt Hill

Characteristics of Multiple Inheritance

• When it is good it is wonderful– A good example is iostreams

• Inherit from a string formatting object (stream) and a file I/O object (io)

• Thus have characteristics of both

• When it is bad it is horrendous– C++ is the main language to retain

multiple inheritance– Smalltalk had it then removed it– Java never had – Eiffel seems to have done the most

with it

Copyright © 1998-2014 Curt Hill

Problems with Multiple Inheritance

• Main problem is name clashes and what to do with them– Suppose two classes have a method X– A new class is a derivation of both

• How do we get one X over the other

• When both ancestors are from same tree problems compound

Copyright © 1998-2014 Curt Hill

Example

• Consider:class grademployee: public grad, public employ{…

• This looks reasonable, but now there are two names, two birth dates, two genders

• How do we distinguish between the access to the grad set_name or the employ set_name?

Conclusion• Inheritance is a powerful

mechanism for reusing code• Function parameters allow us to

unite two similar pieces of code into one

• Inheritance works somewhat similarly by giving new functionality without altering the ancestral class or classes

• Better yet, it is not hard to do

Copyright © 1998-2014 Curt Hill