chapter 9 pointers, virtual functions and polymorphism

Post on 19-Jan-2016

77 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

Chapter 9 Pointers, Virtual Functions and Polymorphism. §9.1 Introduction §9.2 Pointers to Objects §9.3 Virtual Functions §9.4 Dynamic Casting. §9.1 Introduction. Polymorphism: “one name, multiple forms” Functions, data types Function binding Invocation statement  function body - PowerPoint PPT Presentation

TRANSCRIPT

Chapter 9 Pointers, Virtual Functions and Polymorphism

§9.1 Introduction

§9.2 Pointers to Objects

§9.3 Virtual Functions

§9.4 Dynamic Casting

§9.1 Introduction

Polymorphism: “one name, multiple forms” Functions, data types

Function binding Invocation statement function body

Compile time polymorphism Static (early) binding, static linking Function overloading Operator overloading

Run time polymorphism Dynamic (late) binding, dynamic linking Virtual function + pointer of base class

2

Techniques for Polymorphism

3

PolymorphismPolymorphism

Run timepolymorphism

Run timepolymorphism

Compile timepolymorphismCompile timepolymorphism

FunctionOverloading

FunctionOverloading

Operatoroverloading

Operatoroverloading

Virtual functionVirtual function

Example Situation

4

class HM {public: void show(){ cout<<"Human\n"; }};

class HM {public: void show(){ cout<<"Human\n"; }};

class CN: public HM {public: void show(){ cout<<“Chinese\n"; }};

class CN: public HM {public: void show(){ cout<<“Chinese\n"; }};

class CT: public CN{public: void show(){ cout<<“Cantonese\n"; }};

class CT: public CN{public: void show(){ cout<<“Cantonese\n"; }};

int fun(HM h){h.show();}fun(HM());fun(CN());fun(CT());

int fun(HM h){h.show();}fun(HM());fun(CN());fun(CT());

HumanHumanHuman

HumanHumanHuman

HumanChineseCantonese

HumanChineseCantonese

Dynamic bindingDynamic binding

Anonymous object!

Anonymous object!

§9.2 Pointers to Objects

Create objects at run timeclass item {};

item x;

item *it_ptr = &x;

Referring member functionsx.show();

it_ptr->show();

(*it_ptr).show();

Array of objectsitem * ptr = new item[10];

5

6

The “this” Pointer

A special built-in pointer that points to the current object Used to cope with hidden data fields

// Construct a circle object Circle::Circle(double radius) {

this->radius = radius; (*this).radius = radius;

}

// Construct a circle object Circle::Circle(double radius) {

this->radius = radius; (*this).radius = radius;

}

// Set a new radius void Circle::setRadius(double radius) {

this->radius = (radius >= 0) ? radius : 0; }

// Set a new radius void Circle::setRadius(double radius) {

this->radius = (radius >= 0) ? radius : 0; }

The “this” Pointer

Person &Person::greater(Person& x)

{

if (x.age>age)

return x;

else

return *this;

}

max = a.greater(b);

7

the invoking object!

the argument object!

Pointers to Derived Classes

Pointers of a base class type is compatible with pointers of a derived class

Statements for a base class is workable for derived classes

8

B *cptr;//pointer to class B type variable

B b;//base object

D d;//derived object

cptr = &b;//cptr points to object b

cptr->show();

cptr = &d; //cptr points to object d

cptr->show();

class B{

public:

int b;

void show()

{cout<<"b="<<b<<endl;}

};

class D : public B{

public:

int d;

void show(){

cout<<"b="<<b<<endl;

cout<<"d="<<d<<endl;

}

};

9

int main(){

B * bptr; //base pointer

B base; //base object

bptr = &base; bptr->b = 100;

cout<<"bptr …to base…\n“;

bptr->show();

D derived; //derived object

bptr = &derived; bptr->b=200;

cout<<"bptr …to derived…\n“;

bptr->show();

D *dptr;

dptr= &derived; dptr->d=300;

cout<<"dptr is derived type…\n“;

dptr->show();

cout<<"using ((D*)bptr)"<<endl;

((D*)bptr)->d=400;

((D*)bptr)->show();

return 0;

}

§9.3 Virtual Functions

10

The function declared with the keyword “virtual”

Overriding To redefine a virtual function in the derived class

class B { public: virtual string toString() { return "class B"; } };

class B { public: virtual string toString() { return "class B"; } };

class D: public B { string toString() { return "class D"; } };

class D: public B { string toString() { return "class D"; } };

class B {

public:

void display(){

cout<<“Display base";}

virtual void show(){

cout<<“\n show base“;}

};

class D: public B {

public :

void display(){

cout<<"Display derived";}

void show(){

cout<<“show derived";}

};

11

int main(){

B b;

D d;

B *bptr;

cout<<“bptr points to Base“;

bptr=&b;

bptr->display();

bptr->show();

cout<<“bptr points to Derived";

bptr = &d;

bptr->display();

bptr->show();

return 0;

}

Example of Virtual Functions

Realize dynamic binding Must be accessed by using object pointers/references

Must be defined in base class Should be redefined (overriding) in the derived

class If not, base version will be invoked

No virtual constructors Virtual destructors are allowed

Can be a friend of another class

12

Notes on Virtual Functions

Virtual Destructors

13

class B { public: ~B() { cout<<“Dest B\n”; } };

class B { public: ~B() { cout<<“Dest B\n”; } };

class D: public B { public: ~D() { cout<<“Dest D\n”; } };

class D: public B { public: ~D() { cout<<“Dest D\n”; } };

int main() { B *bp = new D(); …… delete bp; …… }

int main() { B *bp = new D(); …… delete bp; …… }

Dest BDest B Dest DDest BDest DDest B

virtual ~B(){virtual ~B(){

Pure Virtual Functions

A function without body does nothing, just a placeholder

Also called abstract function Classes has pure virtual function can’t be used to

create objects Compiler requires each derived class:

define the function, or continue to declare it as a abstract function

14

virtual void display() = 0;

Abstract Classes

15

Class is the abstraction of instances/objects A base class is more abstract/general than

derived classes Abstract class (抽象类 )

In logic: A class so abstract that it cannot have any specific instances It can only be used as base class

In syntax: A class with abstract functions (抽象函数 )

16

Abstract Function

I.e. Pure Virtual Function (纯虚函数 ) Can’t be implemented in abstract classes

For example

GeometricObject -color: string

-filled: bool

#GeometricObject()

#GeometricObject(color: string, filled: bool)

+getColor(): string

+setColor(color: string): void

+isFilled(): bool

+setFilled(filled: bool): void

+tostring(): string

+getArea(): double

+getPerimeter(): double

“ protected”

class GeometricObject{protected: GeometricObject(); GeometricObject(string color, bool filled);

public: string getColor(); void setColor(string color); bool isFilled(); void setFilled(bool filled); string toString(); virtual double getArea() = 0; virtual double getPerimeter() = 0;

private: string color; bool filled;};

class GeometricObject{protected: GeometricObject(); GeometricObject(string color, bool filled);

public: string getColor(); void setColor(string color); bool isFilled(); void setFilled(bool filled); string toString(); virtual double getArea() = 0; virtual double getPerimeter() = 0;

private: string color; bool filled;};

17

Abstract Class Example GeometricObject

-color: string

-filled: bool

#GeometricObject()

#GeometricObject(color: string, filled: bool)

+getColor(): string

+setColor(color: string): void

+isFilled(): bool

+setFilled(filled: bool): void

+tostring(): string

+getArea(): double

+getPerimeter(): double

Circle

-radius: double

+Circle()

+Circle(radius: double)

+Circle(radius: double, color: string, filled: bool)

+getRadius(): double

+setRadius(radius: double): void

+getDiameter(): double

Rectangle -width: double

-height: double

+Rectangle()

+Rectangle(width: double, height: double)

+Rectangle(width: double, height: double, color: string, filled: bool)

+getWidth(): double

+setWidth(width: double): void

+getHeight(): double

+setHeight(height: double): void

AbstractGeometricObject.hAbstractGeometricObject.h

RunRun

AbstractGeometricObject.cppAbstractGeometricObject.cpp

DerivedCircle2.hDerivedCircle2.h

DerivedCircle2.cppDerivedCircle2.cpp

Rectangle2.hRectangle2.h

Rectangle2.cppRectangle2.cpp

TestGeometricObject2 .cppTestGeometricObject2 .cpp

18

§9.4 Dynamic Casting

How to display radius, diameter, area, and perimeter if the object is a circle?

// A function for displaying a geometric objectvoid displayGeometricObject(GeometricObject &object){ cout << "The area is " << object.getArea() << endl; cout << "The perimeter is " << object.getPerimeter() << endl;}

// A function for displaying a geometric objectvoid displayGeometricObject(GeometricObject &object){ cout << "The area is " << object.getArea() << endl; cout << "The perimeter is " << object.getPerimeter() << endl;}

19

Dynamic Casting

The dynamic_cast operator checks if p points to a Circle object If yes, p1 is assigned the address of the object If no, p1 is assigned to NULL (the constant 0)

GeometricObject *p = &object;

Circle *p1 = dynamic_cast<Circle*>(p);

if (p1 != NULL)

{

cout << "The radius is " << p1->getRadius() << endl;

cout << "The diameter is " << p1->getDiameter() << endl;

}

RunRunDynamicCastingDemoDynamicCastingDemo

20

Upcasting and Downcasting

Upcasting Assigning a pointer of a derived class type to a pointer

of its base class type Done implicitly

Downcasting Assigning a pointer of a base class type to a pointer of

its derived class type Done explicitly using dynamic_cast

GeometricObject *p = new Circle(1);Circle *p1 = new Circle(2);p = p1;

GeometricObject *p = new Circle(1);Circle *p1 = new Circle(2);p = p1;

p1 = dynamic_cast<Circle*>(p);p1 = dynamic_cast<Circle*>(p);

21

The typeid Operator

To return the type information of a variable/object The information is stored in an object of class type_info

For example,

string x;cout << typeid(x).name() << endl;string x;cout << typeid(x).name() << endl;

Summary

Polymorphism Compile / Runtime polymorphism Object pointers this pointer Techniques to realize runtime polymorphism

Virtual function Invoked via pointer of base class

Abstract function

22

Review Questions

Q9.2 Q9.4 Q9.8

23

top related