96
03/25/22 Assoc. Prof. Stoyan Bonev 1 COS240 O-O Languages AUBG, COS dept Lecture 01b Title: C++ as O-O Prog Lang (Review) Reference: COS240 Syllabus

10/21/2015Assoc. Prof. Stoyan Bonev1 COS240 O-O Languages AUBG, COS dept Lecture 01b Title: C++ as O-O Prog Lang (Review) Reference: COS240 Syllabus

Embed Size (px)

Citation preview

04/20/23 Assoc. Prof. Stoyan Bonev 1

COS240 O-O Languages AUBG, COS dept

Lecture 01bTitle:

C++ as O-O Prog Lang(Review)

Reference: COS240 Syllabus

04/20/23 Assoc. Prof. Stoyan Bonev 2

Lecture Contents• C++ as O-O Prog Lang

– Brief review

• C++ as O-O Prog Lang– Comprehensive review

• Data Encapsulation and Data Hiding• Inheritance• Polymorphism

04/20/23 Assoc. Prof. Stoyan Bonev 3

Reminder - What is an object?

OBJECT

Operations

Data

set of methods(member functions, methods)

internal state(values of private data members)

04/20/23 Assoc. Prof. Stoyan Bonev 4

Example

#include <iostream>

class circle {

private: double radius;

public: void store(double); double area(void); void display(void);

};

int main(void) { circle c; // an object of circle class c.store(5.0); cout << "The area of circle c is " << c.area() << endl; c.display();}

04/20/23 Assoc. Prof. Stoyan Bonev 5

#include <iostream>

class circle {

private: double radius;

public: void store(double); double area(void); void display(void);

};

// member function definitions void circle::store(double r) {

radius = r;}

double circle::area(void){ return 3.14*radius*radius;}

void circle::display(void){ cout << “r = “ << radius << endl;}

int main(void) { circle c; // an object of circle class c.store(5.0); cout << "The area of circle c is " << c.area() << endl; c.display();}

04/20/23 Assoc. Prof. Stoyan Bonev 6

When declaring an instance of a class, its data members are all uninitialized.

C++ allows objects to initialize themselves when they are created.

This automatic initialization is performed by the use of a constructor function.

A constructor function is a special function that is a member of class and has the same name as that class.

The opposite of the constructor is the destructor. The destructor is called when the object is “destroyed”, allowing any final “house-keeping” activities to be performed. The destructor function has the same name as the constructor but preceded by the tilde (~) symbol.

04/20/23 Assoc. Prof. Stoyan Bonev 7

OOP terminology

• Member functions are referred to as methods.

• Data items are referred to as attributes or instance variables.

• Calling an object’s member function is referred to as sending a message to the object.

04/20/23 Assoc. Prof. Stoyan Bonev 8

Defining the Class

• General syntax

• Access qualifiers: private and public• Data members

– Usually data is private

• Member functions– Usually functions are public

04/20/23 Assoc. Prof. Stoyan Bonev 9

Class SmallObj class SmallObj{ private: int somedata;

public: void SetData(int d) {

somedata = d; }

void ShowData() {

cout << "\nData is =" << somedata; }

};

04/20/23 Assoc. Prof. Stoyan Bonev 10

SmallObj – UML class diagram

SmallObj SmallObj

somedata -somedata

SetData(int) +SetData(int)

ShowData() +ShowData()

04/20/23 Assoc. Prof. Stoyan Bonev 11

Using Class SmallObj

void main(){SmallObj s1, s2; // defining objects

s1.SetData(67); // sending messagess2.SetData(123);

s1.ShowData();s2.ShowData();

}

04/20/23 Assoc. Prof. Stoyan Bonev 12

SmallObj – UML object diagrams

Unlike classes, objects are underlined. Colon ( : ) serves to separate the object name and the class name.

s1:SmallObj somedata=15

s2:SmallObj somedata=173

04/20/23 Assoc. Prof. Stoyan Bonev 13

Class Part /modern version only/

class Part{ private: int modelnumber; int partnumber;

double cost; // modern modelpublic: void setModelNumber(int mdl) { modelnumber = mdl; } int getModelNumber() const { return modelnumber; }

void setPartNumber(int mdl) { partnumber = mdl; } int getPartNumber() const { return partnumber; }

void setCost(double cst) { cost = cst; } double getCost() const { return cost; }

};

04/20/23 Assoc. Prof. Stoyan Bonev 14

Class Part /modern version only/

void main(){ Part p2;

p2.setModelNumber(8124); p2.setPartNumber(516); p2.setCost(314.52); cout << "\n\nPart components:“ <<

p2.getModelNumber() << " " << p2.getPartNumber() << " " << p2.getCost();

cout << '\n' << '\n'; system("pause");}

04/20/23 Assoc. Prof. Stoyan Bonev 15

Evolution of the class concept

• Methods whose type is like ShowData() are considered obsolete and therefore not recommended to be used.

• Instead, a pair of methods associated to each one of the data fields is introduced. They serve for bi-directional (in, out) access to the data field.

• Method Accessor, also ‘getter’ (getX())• Method Mutator, also ‘setter’ (setX())

• Microsoft extends the getX/setX methods to the property concept

04/20/23 Assoc. Prof. Stoyan Bonev 16

C++ Modern Object – native codeusing namespace std;class ModernObject {private: int x;

// constructorspublic: ModernObject() { x = 0; } public: ModernObject(int par) { x = par; }

// obsolete method Show...type() public: void showModernObject() { cout << endl << "Data = " << x ; }

// method accessor public: int getModernObject() { return x; }

// methods mutators public: void setModernObject(int par) { x = par; } public: void setModernObject(int par1, int par2) { x = par1 + par2; } public: void setModernObject(int par1, int par2, int par3) { x = par1 + par2 + par3; }

// properties not supported in native code };// end of class ModernObject

04/20/23 Assoc. Prof. Stoyan Bonev 17

C++ Modern Object – native codevoid main(){

ModernObject a; ModernObject b(15); ModernObject c; a.showModernObject(); b.showModernObject();

// test accessor and mutators methodsc.setModernObject(20); cout << endl << c.getModernObject();c.setModernObject(20,50); cout << endl << c.getModernObject();c.setModernObject(20,30,40); cout << endl << c.getModernObject();

/* // test property// no properties, =>> ,no statements to test properties*/}

04/20/23 Assoc. Prof. Stoyan Bonev 18

C++ objects as Data Types

class Distance

04/20/23 Assoc. Prof. Stoyan Bonev 19

Class Distanceclass Distance { private: int feet; float inches; public:

void SetDist(int ft, float in) { feet = ft; inches = in; } void GetDist()

{ cout <<"\nEnter feet:" ; cin >> feet;cout <<"\nEnter inches:"; cin >> inches;

} void ShowDist()

{cout <<“Feet=" << feet <<" Inches="<< inches;}

};

//=============================================================

void main (){ Distance d1, d2;

d1.SetDist(3, 5.6); cout << "\nDistance components: "; d1.ShowDist(); d2.GetDist(); cout << "\nDistance components: "; d2.ShowDist(); }

04/20/23 Assoc. Prof. Stoyan Bonev 20

C++ objects as general purpose programming elements

class Counter

04/20/23 Assoc. Prof. Stoyan Bonev 21

Class Counterclass Counter{ private: unsigned count; public:

void SetCount(int val) { count = val; }void GetData() { cout <<"\nEnter data:"; cin >> count; }

void ShowData() { cout <<"\nData count is:" << count;}void IncCount() { count++; }unsigned GetCount() { return count; }

};

//=====================================

void main(){

Counter c1; c1.GetData(); c1.ShowData(); c1.IncCount(); c1.ShowData(); cout << "\n" << c1.GetCount(); c1.ShowData();

Counter c2; c2.SetCount(100); cout << "\n\nCounter c2 =" << c2.GetCount(); c2.IncCount(); c2.IncCount(); cout << "\n\nCounter c2 =" << c2.GetCount();

}

04/20/23 Assoc. Prof. Stoyan Bonev 22

C++ objects

Constructors and Destructors

Class Counter class Distance

04/20/23 Assoc. Prof. Stoyan Bonev 23

Constructors and DestructorsClass Counter

class Counter{ private: unsigned count; public:

Counter() { count = 0; }Counter(int val) { count = val; }void SetCount(int val) { count = val; }void GetData() { cout <<"\nEnter data:"; cin >> count;}void ShowData() { cout <<"\nData count is:" << count;}void IncCount() { count++; }unsigned GetCount() { return count; }

};

04/20/23 Assoc. Prof. Stoyan Bonev 24

Constructors and DestructorsClass Counter

void main(){

Counter c1; c1.GetData(); c1.ShowData(); c1.IncCount(); c1.ShowData(); cout << "\n" << c1.GetCount(); c1.ShowData();

Counter c2(100); cout << "\n\nCounter c2 =" << c2.GetCount(); c2.IncCount(); c2.IncCount(); cout << "\n\nCounter c2 =" << c2.GetCount();

}

04/20/23 Assoc. Prof. Stoyan Bonev 25

Constructors and DestructorsClass Distance

class Distance { private: int feet; float inches; public:

Distance() { feet = 0; inches = 0.0; } Distance(int ft, float in) { feet = ft; inches = in; } void SetDist(int ft, float in) { feet = ft; inches = in; } void GetDist() { cout <<"\nEnter feet:" ; cin >>feet;

cout <<"\nEnter inches:"; cin >> inches; } void ShowDist() {

cout <<“Feet=" << feet <<" Inches="<< inches; }

};

04/20/23 Assoc. Prof. Stoyan Bonev 26

Constructors and DestructorsClass Distance

void main (){ Distance d1, d2; d1.SetDist(3, 5.6); cout << "\nDistance components: "; d1.ShowDist();

d2.GetDist(); cout << "\nDistance components: "; d2.ShowDist();

Distance d3(4, 5.45), d4(7, 8.9); cout << "\nDistance components: "; d3.ShowDist(); cout << "\nDistance components: "; d4.ShowDist();}

Moreon

Constructors/Destructors

04/20/23 Assoc. Prof. Stoyan Bonev 28

Constructors & DestructorsGiven class X with two data components

class X { private: int x,y;

public: X(int, int);

. . .

};

There are 3 ways to define constructor X()

X::X(int a, int b)

{ x=a; y=b; }

X::X(int a, int b) : x(a)

{ y=b; }

X::X(int a, int b) : x(a) , y(b)

{ }

04/20/23 Assoc. Prof. Stoyan Bonev 29

Copy constructor and assignment constructor

• If you specify a class with no-constructor, then a no-arg system supported constructor is available

X::X() { . . . } CL::CL() { . . . }• If you define an object whose data components

are initialized (depend on) data components of other objects of the same class, then a system defined (built-in) copy constructor or its overloaded version called assignment constructor is to be used

X::X(X&) CL::CL(CL&)How to pronounce: X of X ref

04/20/23 Assoc. Prof. Stoyan Bonev 30

Copy constructor demo

class CL {private: int x, y;public: CL(); . . . };

// user specified constructorCL::CL(){ cout<<“\nEnter x,y:”; cin>>x>>y; }

void main() { CL obj1; // user specified constructor

CL obj2=obj1;// default copy constructorCL obj3(obj1);

. . . }

04/20/23 Assoc. Prof. Stoyan Bonev 31

Assignment constructor democlass CL { private: int x, y;

public: CL(); CL(CL&); . . . };

// user specified constructorCL::CL(){ cout<<“\nEnter x,y:”; cin>>x>>y; }

// user specified assignment constructorCL::CL(CL& p) { x = p.x +1;

y = p.y +2;}

void main() { CL obj1; // user specified constructor

CL obj2=obj1; // user specified assignment constructorCL obj3(obj1);

. . . }

04/20/23 Assoc. Prof. Stoyan Bonev 32

Objects as Function Arguments

Class Distance

Distance dist1(5, 6.8), dist2(3, 4.5), dist3;

Task: To add two distances using a method:

dist3.AddDist1(dist1, dist2);

04/20/23 Assoc. Prof. Stoyan Bonev 33

Objects as Function Arguments

// void AddDist1(Distance d1, Distance d2);//

void AddDist1(Distance d1, Distance d2) {

feet = d1.feet +d2.feet;inches = d1.inches + d2.inches;if (inches >= 12.) { inches -= 12.; feet++; }

}

04/20/23 Assoc. Prof. Stoyan Bonev 34

Returning Objects from Functions

Class Distance

Distance dist1(5, 6.8), dist2(3, 4.5), dist4;

Task: To add two distances using alternate method:

dist4 = dist1.AddDist2(dist2);

04/20/23 Assoc. Prof. Stoyan Bonev 35

Returning Objects from Functions

// first version of source text Distance AddDist2(Distance d1) {

Distance temp;temp.feet = feet + d1.feet;temp.inches = inches + d1.inches;if (temp.inches >= 12.) {

temp.inches -= 12.; temp.feet++; }return temp;

}

04/20/23 Assoc. Prof. Stoyan Bonev 36

Returning Objects from Functions

// second alternate version of source textDistance AddDist2(Distance d1) {

int ft; float in;ft = feet + d1.feet;in = inches + d1.inches;if (in >= 12.) {

in -= 12.; ft++; }return Distance(ft, in); // anonymous, nameless object

}

Overloaded Operators

04/20/23 Assoc. Prof. Stoyan Bonev 38

Introduction

Why do we need operator overloading?– For better readability

Examples:– Class Counter– Class Distance

04/20/23 Assoc. Prof. Stoyan Bonev 39

IntroductionExample: the Distance class

. . .

Distance d1(5,3.6), d2(6,4.5), d3;

d3.AddDist1(d1,d2);

d3 = d1.AddDist2(d2);

ORd3 = d1 + d2; // OK

04/20/23 Assoc. Prof. Stoyan Bonev 40

Overloading binary operators

04/20/23 Assoc. Prof. Stoyan Bonev 41

Distance overloaded operator +

One more method:Distance operator+(Distance d2){

int ft = feet + d2.feet; float in = inches + d2.inches;if (in >=12.) { ft++; in-=12.; }return Distance (ft, in);

}

Distance d1(6, 5.18), d2=3.5, d3, d4, d5; d3 = d1 + d2; d3 = d1.operator+(d2);

04/20/23 Assoc. Prof. Stoyan Bonev 42

Distance overloaded comparison operators

class Distance { private: int feet; float inches; public: Distance() { feet = 0; inches = 0.0; }

Distance (int ft, float in) { feet = ft; inches = in; } void ShowDist() { cout <<"\nDistObject= " << feet <<" "<< inches; } bool operator < (Distance) const;};

bool Distance::operator < (Distance d2) const{ float bf1 = feet + inches/12; float bf2 = d2.feet + d2.inches/12; return (bf1 < bf2) ? true : false;}

};

void main() { Distance dist1(5, 6.8), dist2(3, 4.5); if (dist1<dist2) cout << “\n dist1 object is less than dist2 object”;

// OR if (dist1.operator<(dist2)) cout << “\n dist1 is less than dist2”; }

04/20/23 Assoc. Prof. Stoyan Bonev 43

Overloading unary operators

04/20/23 Assoc. Prof. Stoyan Bonev 44

Counter overloaded operator ++

class Counter {

void IncCount() { count++; }void operator++() {count++;}

};

Counter c(100); c.IncCount(); ++c; c.operator++(); //OK

04/20/23 Assoc. Prof. Stoyan Bonev 45

Counter overloaded operator ++ class Counter

{void IncCount() { count++; }void operator++() { count++; }

};

Counter c(100); c.IncCount(); ++c; c.operator++(); //OK

Counter d(300), e; ++d; //OK e = ++d; // NOT OK

04/20/23 Assoc. Prof. Stoyan Bonev 46

Counter overloaded operator ++ class Counter{ private: unsigned count; public: Counter() { count = 0; }

Counter(int val ) { count = val; } void IncCount() { count++; } void GetData() { cout <<"\nEnter data:"; cin >> count;} void ShowData() { cout <<"\nData count is:" << count; } unsigned GetCount() { return count; } // overloaded unary operator ++, first version Counter operator++() {

count++;return Counter(count);

}};

04/20/23 Assoc. Prof. Stoyan Bonev 47

Overloaded operators as member functions of a class:

• The Rule:

Overloaded operator always requires one less argument than its number of operands, since one operand is the object of which the operator is a member function.

• This rule not valid for friend functions.

04/20/23 Assoc. Prof. Stoyan Bonev 48

INHERITANCE

• Base class and Derived classes;

• Access control;

• Class hierarchies;• Multiple inheritance.

04/20/23 Assoc. Prof. Stoyan Bonev 49

The Concept of Inheritance• Inheritance is the process of creating new

classes, called derived classes from existing or base classes.

• The derived class inherits the capabilities of the base class but can add refinements of its own.

• The base class stays unchanged with this process.

• Usually the derived class is functionally more powerful or specialized compared to the base class.

04/20/23 Assoc. Prof. Stoyan Bonev 51

A-Kind-Of relationship

Illustration of ''a-kind-of'' class level relationship

In this figure, classes are drawn using rectangles. Their name always starts with an uppercase letter. The arrowed line indicates the direction of the relation, hence, it is to be read as ”Circle is a-kind-of Point”.

04/20/23 Assoc. Prof. Stoyan Bonev 52

Is-A relationship

In this figure, objects are drawn using rectangles with round corners. Their name only consists of lowercase letters. The arrowed line indicates the direction of the

relation, hence, it is to be read as ”circle is a point”.

Illustration of ''is-a'' instance level relationship

04/20/23 Assoc. Prof. Stoyan Bonev 53

A SubClass inherits all the attributes and behaviors of the SuperClass, and may have

additional attributes and behaviors.

.

                                                                                              

                   

04/20/23 Assoc. Prof. Stoyan Bonev 54

Specifying Derived class (C++)

class Base { . . . };

// Derived1 class publicly derived from Base class class Derived1: public Base {. . .

};

// Derived2 class privately derived from Base class class Derived2: private Base {. . .

};

04/20/23 Assoc. Prof. Stoyan Bonev 55

Accessing base class members

• The protected access specifier

class Base { private: . . .

protected: . . .

public: . . . };

04/20/23 Assoc. Prof. Stoyan Bonev 56

Substituting Base class members

DecrementCounter (1st version)

class CountDn : public Counter{

. . .};

04/20/23 Assoc. Prof. Stoyan Bonev 57

Class CountDn (1st idea)class Counter{ protected: unsigned count; public: void GetData() { cout <<"\nEnter data:"; cin >> count; }

void ShowData() { cout <<"\nData count is:" << count;}void IncCount() { count++; }

};class CountDn : public Counter{ public: void DecCount() { count--; }};void main(){ Counter c1; c1.GetData(); c1.ShowData(); c1.IncCount();

c1.ShowData(); CountDn c3; c3.GetData(); c3.incCount(); c3.IncCount(); c3.ShowData();

c3.DecCount(); c3.ShowData():}

04/20/23 Assoc. Prof. Stoyan Bonev 58

Generalization in UML Class diagrams

Counter#count+GetData()+ShowData()+IncCount()

CountDn

+DecCount()

04/20/23 Assoc. Prof. Stoyan Bonev 59

Class CountDn (working demo)class Counter{ protected: unsigned count;

public: Counter() { count = 0; } Counter(int val ) { count = val; } void IncCount() { count++; } void GetData() { cout <<"\nEnter data:"; cin >> count;} void ShowData() { cout <<"\nData count is:" << count; } unsigned GetCount() { return count; } Counter operator++(int ) { count++; return Counter(count); } Counter operator++( ) { count++; return Counter(count); }

};

class CountDn : public Counter{ public: Counter operator--() { count--; return Counter(count); }};

04/20/23 Assoc. Prof. Stoyan Bonev 60

Derived class constructors Class CountDn

class Counter{ protected: unsigned count; public: Counter() { count = 0; }

Counter(int val ) { count = val; } void IncCount() { count++; } void GetData() { cout <<"\nEnter data:"; cin >> count;} void ShowData() { cout <<"\nData count is:" << count; } unsigned GetCount() { return count; } Counter operator++(int ) { count++; return Counter(count); } Counter operator++( ) { count++; return Counter(count); }

};

class CountDn : public Counter{ public: CountDn() : Counter() { }

CountDn(int val) : Counter(val) { }Counter operator--() { count--; return CountDn(count); }

};

04/20/23 Assoc. Prof. Stoyan Bonev 61

Multiple Inheritance

Example: 2 Base classes, 3+1 Derived classes

Base classes: Derived classes:

class Employee class Manager

class Student class Scientist

class Laborer

class Foreman

04/20/23 Assoc. Prof. Stoyan Bonev 62

Real Multiple Inheritance

Student Employee

diploma name, id

Manager Scientist Laborer

title publications

04/20/23 Assoc. Prof. Stoyan Bonev 63

Ambiguity in multiple inheritance- problem 1

class A { public: void Show() { cout<<“A”; } }; class B { public: void Show() { cout<<“B”; } }; class C : public A, public B { . . . }; void main() {

C objc;objc.Show(); // ambiguous – will not compileobjc.A::Show(); // OKobjc.B::Show(); // OK

}

04/20/23 Assoc. Prof. Stoyan Bonev 64

Containership• Classes within classes. Possible relations:

B is a kind of A. | B has an object of | class A.

| A is a part-of B. Relation based on | Relation within

Inheritance | independent classes |

class A { . . . }; | class A { . . . }; class B : public A | class B { . . . }; | { . . .

| A obja; | };

04/20/23 Assoc. Prof. Stoyan Bonev 65

Containership• Classes within classes. Has-a relation:Aggregation is called a “has a” relation. We say:

Library has a book.Invoice has a line item.

Aggregation is also called a “part-whole” relation.The book is part of the library.

In OOP, aggregation may occur when an object is an attribute of another. See previous slide.

In UML, aggregation is considered a special kind of association. It’s safe to call a relation an association but if class A contains object of class B, and is organizationally superior to class B, it’s a good candidate for aggregation.

04/20/23 Assoc. Prof. Stoyan Bonev 66

Aggregation

• Aggregation is shown in the same way as association in UML class diagrams except that the “whole” end of the association line has an open diamond-shaped arrowhead.

Library

Books Staff

04/20/23 Assoc. Prof. Stoyan Bonev 67

Composition: a stronger Aggregation

• Composition has characteristics of aggregation plus:– The part may belong to only one a whole– The lifetime of the part is the same as the lifetime of the

whole

Car

Doors Engine

04/20/23 Assoc. Prof. Stoyan Bonev 68

Polymorphism

• Early binding and Late binding;–Regular member functions;–virtual member functions;

–Methods accessed with pointers.

04/20/23 Assoc. Prof. Stoyan Bonev 69

What is polymorphism?

• Giving different meanings to the same thing).

Early binding operates on regular /normal/ member functions (methods) accessed with pointers.

Late binding operates on virtual member functions (methods) accessed with pointers..

• Regular /normal/ and virtual methods accessed via pointers. Examples:

BaseDerived1, Derived2

classes

Person Professor, Student

classes

04/20/23 Assoc. Prof. Stoyan Bonev 70

Early binding / Late binding

virtual vs. non virtual methodsFirst example on Polymorphism: method

Show() class Base { . . . };

class Derived1 : public Base { . . . }; class Derived2 : public Base { . . . };

Derived1 drv1; Derived2 drv2; Base *ptr; ptr = &drv1; ptr->Show();

ptr = &drv2; (*ptr).Show();

04/20/23 Assoc. Prof. Stoyan Bonev 71

Early Binding (at compile time)

Normal, regular, non virtual methods class Base {public: void Show(){ cout << "\n Base:" ; }};

class Derived1 : public Base {public: void Show(){ cout << "\n Derived1:" ; } };

class Derived2 : public Base {public: void Show(){ cout << "\n Derived2:" ; } };

Major factor/condition: the type of the ptr pointer – object of Base class Derived1 drv1; Derived2 drv2; Base *ptr; ptr = &drv1; ptr->Show();

ptr = &drv2; (*ptr).Show();

OOP3a.cpp OOP3aEarly.exe

04/20/23 Assoc. Prof. Stoyan Bonev 72

Early Binding (at compile time)

The compiler ignores the contents of the pointer ptr and selects the member function that matches the type of the pointer.

See figure on next slide.

04/20/23 Assoc. Prof. Stoyan Bonev 73

Early Binding (at compile time)

04/20/23 Assoc. Prof. Stoyan Bonev 74

Late Binding (at run time)

Virtual methods class Base {public: virtual void Show(){ cout << "\n Base:" ; } };

class Derived1 : public Base {public: void Show(){ cout << "\n Derived1:" ; } };

class Derived2 : public Base {public: void Show(){ cout << "\n Derived2:" ; } };

Major factor/condition: contents of the ptr pointer – obj of derived class Derived1 drv1; Derived2 drv2; Base *ptr; ptr = &drv1; ptr->Show();

ptr = &drv2; (*ptr).Show();

OOP3a.cpp OOP3aLate.exe

04/20/23 Assoc. Prof. Stoyan Bonev 75

Late Binding (at run time)

The compiler selects the function based on the contents of the pointer ptr, not on the type of the pointer.

See figure on next slide.

04/20/23 Assoc. Prof. Stoyan Bonev 76

Late Binding (at run time)

04/20/23 Assoc. Prof. Stoyan Bonev 77

Late Binding (at run time)

Pure virtual methodsA virtual function with no body that is never executed.

class Base { public: virtual void Show() = 0 ;};

class Derived1 : public Base {

public: void Show(){ cout << "\n Derived1:" ;} };

class Derived2 : public Base {

public: void Show(){ cout << "\n Derived2:" ;} };

04/20/23 Assoc. Prof. Stoyan Bonev 78

Early binding / Late binding

virtual vs. non virtual methods Second example on Polymorphism:

method isOutstanding()

class Person { . . . };

class Professor: public Person { . . . }; class Student: public Person { . . . };

04/20/23 Assoc. Prof. Stoyan Bonev 79

Virtual method IsOutstanding()class Person { protected: char name[20]; public:

void GetName() { cout << "\nEnter name:"; cin >> name; } void ShowName() { cout << "\n Name is:" << name << " "; } bool virtual isOutStanding() = 0;

};

04/20/23 Assoc. Prof. Stoyan Bonev 80

Virtual method IsOutstanding()

class Student : public Person{ private: float score; public:

void GetScore() {

cout << "\n Enter student's score:"; cin >> score;

} bool isOutStanding() {

return (score > 98.0) ? true: false; }

};

04/20/23 Assoc. Prof. Stoyan Bonev 81

Virtual method IsOutstanding()class Professor : public Person{ private: int NumPubs; public:

void GetNumPubs() { cout << "\n Enter number of professor's publications:"; cin >> NumPubs; } bool isOutStanding() { return (NumPubs > 100) ? true: false; }

};

04/20/23 Assoc. Prof. Stoyan Bonev 82

Virtual method IsOutstanding()void main (){ Person *PersPtr[100]; Student *StuPtr; Professor *ProPtr; int n=0; char choice; do {

cout << "\n Enter student or professor (s/p)?:"; cin >> choice; if (choice == 's') {

StuPtr = new Student; StuPtr->GetName(); StuPtr->GetScore(); PersPtr[n++] = StuPtr;

} else {

ProPtr = new Professor; ProPtr->GetName(); ProPtr->GetNumPubs(); PersPtr[n++] = ProPtr; }

cout << "\n\n Enter another (y/n)?:"; cin >> choice;} while (choice == 'y'); // end of do

for (int j=0; j<n; j++) {PersPtr[j]->ShowName();if (PersPtr[j]->isOutStanding() == true) cout << " --outstanding person";

} // end of for }// end of main()

04/20/23 Assoc. Prof. Stoyan Bonev 83

Polymorphism in C++ classified

• Dynamic polymorphism – Based on late binding and virtual methods

• Static or ad-hoc polymorphism – – Based on overloaded functions concept

• Parametric (generic) polymorphism – – Based oh template reserved word

Generic Classes in C++

04/20/23 Assoc. Prof. Stoyan Bonev 85

Generic Classes in C++

• General form of a generic class definition:template <class parameters> followed by a class definition that may include the class parameters

• Class parameters form (there must be at least one):

class identifier

04/20/23 Assoc. Prof. Stoyan Bonev 86

Task: to implement 4 classes with the same structure that differ by the type of a data

component class X1{ private: char item; public: X1() { item = 0;}

X1(char v) { item = v; }char getItem() { return item; }void setItem(char p) { item = p; }

}; . . . X1 obj1; obj1.setItem(‘x’); cout << obj1.getItem();

04/20/23 Assoc. Prof. Stoyan Bonev 87

Task: to implement 4 classes with the same structure that differ by the type of a data

component class X2{ private: int item; public: X2() { item = 0;}

X2(int v) { item = v; } int getItem() { return item; }void setItem(int p) { item = p; }

}; . . . X2 obj2; obj2.setItem(23); cout << obj2.getItem();

04/20/23 Assoc. Prof. Stoyan Bonev 88

Task: to implement 4 classes with the same structure that differ by the type of a data

component class X3{ private: float item; public: X3() { item = 0;}

X3(float v) { item = v; }float getItem() { return item; }void setItem(float p) { item = p; }

}; . . . X3 obj3; obj3.setItem(2.71f); cout << obj3.getItem();

04/20/23 Assoc. Prof. Stoyan Bonev 89

Task: to implement 4 classes with the same structure that differ by the type of a data

component class X4{ private: double item; public: X4() { item = 0;}

X4(double v) { item = v; }double getItem() { return item; }void setItem(double p) { item = p; }

}; . . . X4 obj4; obj4.setItem(3.14159265); cout << obj4.getItem();

04/20/23 Assoc. Prof. Stoyan Bonev 90

The solution: generic class definition

template <class Type > class X { private: Type item; public: X() { item = 0;}

X(Type v) { item = v; } Type getItem() { return item; }void setItem(Type p) { item = p; }

};

04/20/23 Assoc. Prof. Stoyan Bonev 91

The solution: generic class definition

. . .

X<char> obj1;

X<int> obj2;

X<float> obj3;

X<double> obj4;

04/20/23 Assoc. Prof. Stoyan Bonev 92

Demo program oop5b.cpp oop5b.exe

Generic stack class definition template <class TYPE, int SIZE> class Stack { public: Stack() { . . .}

void push(TYPE var) { . . . } TYPE pop() { . . . }

private: TYPE st[SIZE]; int sp; }; . . . Stack<int, 100> c1; Stack<float, 200> c2;

04/20/23 Assoc. Prof. Stoyan Bonev 93

Demo program oop5b.cpptemplate <class TYPE, int SIZE>class Stack{ private: TYPE st[SIZE]; int sp; public:

Stack() { sp = -1; } // constructor void push(TYPE var){ if (sp < SIZE-1)

{ sp++; st[sp] = var; }else { cout << "\n Stack full\n"; getch(); exit(1); }

}TYPE pop(){ TYPE pom; if (sp>=0)

{ pom = st[sp]; sp--; return pom; } else

{ cout << "\n Stack empty\n"; getch(); exit(2); } } ~Stack() { cout << endl << "GOOD Bye"; } // Destructor

};

04/20/23 Assoc. Prof. Stoyan Bonev 94

Demo program oop5b.cppmain(){

Stack<int, 100> c1; c1.push(22); c1.push(33); cout << c1.pop();

Stack<float, 10> M;

M.push(11.2); M.push(22.4); M.push(33.6); M.push(44.8); M.push(55.9); M.push(66.6); cout << "\n\nStack contents" << endl;

cout << M.pop() << endl; cout << M.pop() << endl; cout << M.pop() << endl; cout << M.pop() << endl; cout << M.pop() << endl; cout << M.pop() << endl; cout << M.pop() << endl;

char ch; cin>> ch;}

04/20/23 Assoc. Prof. Stoyan Bonev 95

Polymorphism in C++ classified

• Parametric (generic) polymorphism– Based oh template reserved word

• Static or ad-hoc polymorphism– Based on overloaded functions concept

• Dynamic polymorphism– Based on late binding and virtual methods

Thank Youfor

Your attention!