0% found this document useful (0 votes)
44 views41 pages

4-Oop 2016-SPR CH15

The preceding code is not polymorphic because it calls the id() function based on the type of the pointer variable, not the actual object being pointed to. Since all the pointers are of type Animal*, it will always call the Animal version of id(), even if the object is actually a Dog or Cat. For the code to be polymorphic and call the correct id() method based on the actual object type, the id() function needs to be declared as virtual in the base Animal class: class Animal{ public: virtual void id(){cout << "animal";} }; Now when id() is called via an Animal* pointer, it will dispatch to the correct overridden version in the derived class at runtime based

Uploaded by

yjshin0920
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views41 pages

4-Oop 2016-SPR CH15

The preceding code is not polymorphic because it calls the id() function based on the type of the pointer variable, not the actual object being pointed to. Since all the pointers are of type Animal*, it will always call the Animal version of id(), even if the object is actually a Dog or Cat. For the code to be polymorphic and call the correct id() method based on the actual object type, the id() function needs to be declared as virtual in the base Animal class: class Animal{ public: virtual void id(){cout << "animal";} }; Now when id() is called via an Animal* pointer, it will dispatch to the correct overridden version in the derived class at runtime based

Uploaded by

yjshin0920
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

Administrivia

 One suggestion
 Fast to follow
 No need to poll
 Some are still boring, some are having troubles
 Can we slow down?
 Future Schedules
 We have final presentation
 I am preparing extra lectures for technical programming tips
 Surprise: Your have learned basic grammar of C++ already
 Next lectures on
 STL, Memory management
 Searching, sorting, Recursion
 Library, Makefile
1
Administrivia
 Please
 Surprise: Your have learned basic grammar of C++ already
 Read book chapters every time after class
 Practice the concepts while you are doing TP
 Start your TP ASAP

 But I will review every time to help you


 Bring your in-class questions for you and your friends, PLEASE
 Extra points are still in action. Email me for points.
 Once I notice your question point, I will prepare extra ppts for your
understanding
 ANYTIME, Use Piazza or Email me or TAs
 I am trying to answer back ASAP within few hours
 For assignment inputs, email TAs
2
Polymorphism and Virtual
Functions
Chapter 15

Instructor: Sungahn Ko
2016 Spring CSE24101
Example
class AAA {
public:
AAA
(virtual) void fct() {
cout << “AAA"; }};

class BBB: public AAA {


public: BBB
void fct() {
cout << “BBB”
Result?
int main() { w/ or w/o virtual?
BBB b;
b.fct();
}
Output: BBB
Always.
This is static binding

4
Example
class AAA {
public:
AAA
(virtual) void fct() {
cout << “AAA"; }};

class BBB: public AAA {


public: BBB
void fct() {
cout << “BBB”
int main() {
BBB * b = new BBB; w/o virtual output:
b-> fct();
AAA* a = b; BBB
A->fct();
AAA
}
w/ virtual output
BBB BBB
5
Example
class Car {
public:
Car
virtual void Create() {
cout << " Car\n"; }};

class Sedan: public Car {


public: Sedan
void Create() {
cout << " Sedan }};
int main() {
w/o virtual: Car, Car
Car *x, *y; w/ virtual: Car, Sedan
x = new Car();
x->Create();
y = new Sedan();
A question from a student?
y->Create();
} w/ virtual at Sedan Create:
Car, Car
6
VTABLE

7
15.1 Type Compatibility in
Inheritance Hierarchies

 Classes lower in the


hierarchy are special general Animal
case
cases of those above
-Sometimes, we may want to Cat Dog
instantiate all of these for
purposes
-But based on situations, I
want my instances act
differently. special
- How to easily do this? case Poodle
Polymorphism in OOP

8
Q&A

9
Type Compatibility in Inheritance
 A pointer to a derived class can be assigned to a
pointer to a base class. Another way to say this is:
 A base class pointer can point to derived class
objects
Animal *pA = new Cat;

10
Type Compatibility in Inheritance
 Assigning a base class pointer to a derived class
pointer requires a cast

Animal *pA = new Cat;


Cat *pC;
pC = static_cast<Cat *>(pA);

 The base class pointer must already point to a


derived class object for this to work

11
Using Type Casts with Base Class
Pointers
 C++ uses the declared type of a pointer to determine
access to the members of the pointed-to object
 If an object of a derived class is pointed to by a base
class pointer, all members of the derived class may not be
accessible
 Type cast the base class pointer to the derived class (via
static_cast) in order to access members that are
specific to the derived class

12
Example
enum Discipline { ARCHEOLOGY, BIOLOGY, class Faculty:public Person
COMPUTER_SCIENCE }; {
class Person private:
{ Discipline department;
protected: public:
string name; //constructor
public: Faculty(string fname, Discipline d) :
Person() { setName(""); } Person(fname)
Person(string pName) { setName(pName); } {
void setName(string pName) department = d;
{ name = pName; } }
string getName() { return name;} void setDepartment(Discipline d)
}; { department = d; }
Discipline getDepartment( )
{ return department; }
};

13
Example
class TFaculty : public Faculty
{
private:
string title; Person
public:
TFaculty(string fname, Discipline d, string title)
: Faculty(fname, d) { setTitle(title); }
void setTitle(string title) { this->title = title; }
//override getName() Faculty
string getName( )
{ return title + " " + Person::getName();}
};

TFaculty

14
Using Type Casts with Base Class
Pointers
// pPerson actually points to Faculty object
// but not aware of additional members of
// Faculty class
Person *pPerson = new Faculty(“Donald Knuth”,
COMPUTER_SCIENCE);

pPerson->setDepartment(BIOLOGY); // compile error!

static_cast<Faculty*>(pPerson)->setDepartment(BIOLOGY);
// work!

15
Example
int main() cout << static_cast<TFaculty *>(pp)->getName()
{ Person *pp; << endl;

Faculty *pf;
TFaculty *ptf; // Assigment from base to derived needs a cast.

ptf = new TFaculty("Indiana Jones", TFaculty *ptf1;


ARCHEOLOGY, "Dr."); ptf1 = static_cast<TFaculty *>(pp);
cout << "Get name through a pointer to cout << "Get name through a pointer to TFaculty: ";
TFaculty: "; cout << ptf1->getName();
cout << ptf->getName() << endl; return 0;
}
pf = ptf;
cout << "Get name through a pointer to Get name through a pointer to TFaculty: Dr. Indiana
Faculty: "; Jones
cout << pf->getName() << endl; Get name through a pointer to Faculty: Indiana Jones
Get name through a cast to pointer to TFaculty: Dr.
pp = ptf; Indiana Jones

cout << "Get name through a cast to pointer Get name through a pointer to TFaculty: Dr. Indiana
to TFaculty: "; Jones

16
15.2 Polymorphism and Virtual
Member Functions
 Polymorphic code: Code that behaves differently when
it acts on objects of different types

 Virtual Member Function: The C++ mechanism for


achieving polymorphism

17
Polymorphism
Consider the Animal,
Cat, Dog hierarchy
where each class has Animal
its own version of the
member function
id( ) Cat Dog

Poodle

18
Polymorphism
class Animal{
public: void id(){cout << "animal";}
}

class Cat : public Animal{


public: void id(){cout << "cat";}
}

class Dog : public Animal{


public: void id(){cout << "dog";}
}

19
Polymorphism
 Consider the collection of different Animal objects

Animal *pA[] = {new Animal,


new Dog,
new Cat};

for(int k=0; k<3; k++)


pA[k]->id();

 Q: What will be printed out?


A: Prints animal animal animal, ignoring the more specific versions
of id() in Dog and Cat

20
Polymorphism
 Preceding code is not polymorphic: it behaves the same
way even though Animal, Dog and Cat have different
types and different id() member functions
 Polymorphic code would have printed "animal dog
cat" instead of "animal animal animal"

21
Polymorphism
 The code is not polymorphic because in the expression
pA[k]->id()
the compiler sees only the type of the pointer pA[k],
which is pointer to Animal

 Compiler does not see type of actual object pointed to,


which may be Animal, or Dog, or Cat

22
Virtual Functions
Declaring a function virtual will make the compiler
check the type of each object in run-time to see if it is
a more specific version of the object.

23
Virtual Functions
class Animal{
public: virtual void id(){cout << "animal";}
}
class Cat : public Animal{
public: virtual void id(){cout << "cat";}
}
class Dog : public Animal{
public: virtual void id(){cout << "dog";}
}
----------------
class Animal{
public: void id(){cout << "animal";}
}
class Dog : public Animal{
One question from
public: virtual void id(){cout << “Dog";}
last class
}
Virtual in Dog
class Poodle : public Dog{
Result?
public: void id(){cout << “Poodle";}
}
24
Virtual Functions
No virtual

1. Virtual for id() in Animal


Animal dog poodle

2. no virtual for id() in Animal


Animial animial animial

3. Virtual for id2()


Dog2 poodle2
Compared to case 1, 3 above

4. Virtual for id() in Dog


Check it out!!!!

I will post this code at BB


Play with this for your
25 understanding
Static binding & virtual

w/o virtual:
Car
Car

w/ virtual in Car:
Car
Sedan

I will post this code at


BB
Play with virtual for
your understanding

26
Virtual Functions
If the member functions id()are declared virtual, then
the code
Animal *pA[] = {new Animal,
new Dog,
new Cat};
for(int k=0; k<3; k++)
pA[k]->id();
will print animal dog cat

27
Function Binding
 In pA[k]->id(), compiler must choose which
version of id() to use: There are different versions in
the Animal, Dog, and Cat classes
 Function binding is the process of determining which
function definition to use for a particular function call
 The alternatives are static and dynamic binding

28
Static Binding
 Static binding chooses the function in the class of the
base class pointer, ignoring any versions in the class of
the object actually pointed to
 Static binding is done at compile time

29
Dynamic Binding
 Dynamic Binding determines the function to be invoked at
execution time
 Can look at the actual class of the object pointed to and
choose the most specific version of the function
 Dynamic binding is used to bind virtual functions

30
15.3 Abstract Base Classes and Pure
Virtual Functions
 An abstract class is a class that must be instantiated as
one of its subclasses (derived classes)

 For example, in real life, Animal is an abstract class: there


are no animals that are not dogs, or cats, or lions…

31
Abstract Base Classes and Pure
Virtual Functions
 Abstract classes are an organizational tool: useful in
organizing inheritance hierarchies

 Abstract classes can be used to specify an interface that


must be implemented by all subclasses

32
Abstract Functions
 The member functions specified in an abstract class do
not have to be implemented
 The implementation is left to the subclasses
 In C++, an abstract class is a class with at least one
abstract member function

33
Abstract Functions
(Pure Virtual Functions)
 In C++, a member function of a class is declared to be an
abstract function by making it virtual and replacing its body
with = 0;
class Animal{
public:
virtual void id()=0;
};

 A virtual function with its body omitted and replaced with =0


is called a pure virtual function, or an abstract function

34
Abstract Classes
 An abstract class can not be instantiated
 An abstract class can only be inherited from: that is, you
can derive classes from it
 Classes derived from abstract classes must override the
abstract (pure virtual) function with a concrete member
function before they can be instantiated.
 Note : The member functions in an abstract class do not have to
be implemented by sub-classes.

35
Abstract Classes
class Shape class Rectangle : public Shape
{ {
protected: public:
int posX, posY; virtual void draw(){
public: cout << “Rectangle at "
virtual void draw() = 0; << posX << " “ << posY
void setPosition(int pX,int pY) << endl;}
{ };
posX = pX;
posY = pY; class Hexagon : public Shape
} {
}; public:
virtual void draw(){
cout << “Hexagon at "
<< posX << " “ << posY
<< endl;}
};

36
Abstract Classes
int main() {
// Create array of pointers to Shapes of various types.
const int NUM_SHAPES = 3;
Shape * shapeArray[] = { new Hexagon, new Rectangle,
new Hexagon};
// Set positions of all the shapes.
int posX = 5, posY = 15;
for (int k = 0; k < NUM_SHAPES; k++) {
shapeArray[k]->setPosition(posX, posY);
posX += 10;
posY += 10; };
// Draw all the shapes at their positions.
for (int j = 0; j < NUM_SHAPES; j++)
shapeArray[j]->draw();
return 0; }

Hexagon at 5 15
Rectangle at 15 25
Hexagon at 25 35
37
Q&A

38
Virtual Goes Downward
class Animal{
public: virtual void id(){cout << "animal";}
}
class Cat : public Animal{
public: virtual void id(){cout << "cat";}
}
class Dog : public Animal{
public: virtual void id(){cout << "dog";}
}
----------------
class Animal{
public: void id(){cout << "animal";}
}
class Dog : public Animal{
public: virtual void id(){cout << “Dog";}}
class Poodle : public Dog{
public: void id(){cout << “Poodle";}}//don’t need to add virtual

Overriding only works from Dog, does not work for Animal’s
id() 39
VTABLE

40
Virtual -> DOWNWARD
class base {
public:
void fun() { cout<<"base"; }
};

class derived : public base {


public:
virtual void fun() {cout<<" derived";}
};

main() {
base *p;
derived d;
p=&d;
p->fun();
return 0;
}

Output : base
41

You might also like