0% found this document useful (0 votes)
59 views26 pages

Why Are Virtual Functions Needed?

The document discusses virtual functions and polymorphism in C++. Virtual functions allow functions of derived classes to be called through pointers or references to the base class. This allows different classes to respond appropriately to the same function call, depending on the actual object. To enable polymorphism, the function must be declared as virtual in the base class. Abstract base classes contain at least one pure virtual function, which enforces derivation but prevents objects of the base class. Virtual functions allow polymorphic behavior that is key to object-oriented programming.

Uploaded by

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

Why Are Virtual Functions Needed?

The document discusses virtual functions and polymorphism in C++. Virtual functions allow functions of derived classes to be called through pointers or references to the base class. This allows different classes to respond appropriately to the same function call, depending on the actual object. To enable polymorphism, the function must be declared as virtual in the base class. Abstract base classes contain at least one pure virtual function, which enforces derivation but prevents objects of the base class. Virtual functions allow polymorphic behavior that is key to object-oriented programming.

Uploaded by

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

Virtual Functions (Background)

• Virtual means existing in appearance but not in reality.


• When virtual functions are used, a program that appears to be calling a
function of one class may in reality be calling a function of a different class.
• Why are virtual functions needed?
Suppose you have a number of objects of different classes but you want to put
them all in an array and perform a particular operation on them using the
same function call. For example, suppose a graphics program includes several
different shapes: a triangle, a ball, a square, and so on.” Each of these classes
has a member function draw() that causes the object to be drawn on the
screen.
Now suppose you plan to make a picture by grouping a number of these
elements together, and you want to draw the picture in a convenient way. One
approach is to create an array that holds pointers to all the different objects in
the picture.
Virtual Functions (Background)- continue

• The array might be defined like this:


• shape* ptrarr[100]; // array of 100 pointers to shapes

• If you insert pointers to all the shapes into this array, you can then draw an
entire picture usinga simple loop:

for(int j=0; j<N; j++)


ptrarr[j]->draw();

• This is an amazing capability: Completely different functions are executed


by the same function call.
Virtual Functions ( Polymorphism)

• If the pointer in ptrarr points to a ball, the function that draws a ball is
called;
• If itpoints to a triangle, the triangle-drawing function is called.
• This is called polymorphism, which means different forms. The functions
have the same appearance, the draw() expression, but different actual
functions are called, depending on the contents of ptrarr[j].
• Polymorphism is one of the key features of object-oriented programming,
after classes and inheritance.
Polymorphism- Condition

• For the polymorphic approach to work, several conditions must be


met.

• First, all the different classes of shapes, such as balls and triangles, must be
descended from a single base class (called shape in MULTSHAP).

• Second, the draw() function must be declared to be virtual in the base class.
Virtual Functions ( Polymorphism)
• Our first example shows what happens when a base class and derived classes all have
functions with the same name, and you access these functions using pointers but without
using virtual functions.
#include <iostream> class Derv2 : public Base //derived class 2
using namespace std; {
class Base //base class public:
{ void show()
public: { cout << “Derv2\n”; }
void show() };
{ cout << “Base\n”; } int main()
}; {
class Derv1 : public Base //derived class 1 Derv1 dv1; //object of derived class 1
{ Derv2 dv2; //object of derived class 2
public: Base* ptr; //pointer to base class
void show() ptr = &dv1; //put address of dv1 in pointer
{ cout << “Derv1\n”; } ptr->show(); //execute show()
}; ptr = &dv2; //put address of dv2 in pointer
ptr->show(); //execute show() Error??????
return 0;
}
Virtual Functions ( Polymorphism)
• The rule is that pointers to objects of a derived class are type
compatible with pointers to objects of the base class.
• Now the question is, when you execute the line
ptr->show();
what function is called? Is it Base::show() or Derv1::show()?
• The output from the program answers these questions: Output:
• Base
• Base

• As you can see, the function in the base class is always executed. The
compiler ignores the contents of the pointer ptr and chooses the
member function that matches the type of the pointer.
Virtual Functions ( Polymorphism)
Virtual Member Functions Accessed with Pointers
#include <iostream> class Derv2 : public Base //derived class 2
using namespace std; {
public:
class Base //base class void show()
{ { cout << “Derv2\n”; }
public: };
virtual void show() //virtual function
{ cout << “Base\n”; } int main()
}; {
Derv1 dv1; //object of derived class 1
class Derv1 : public Base //derived class 1 Derv2 dv2; //object of derived class 2
{ Base* ptr; //pointer to base class
public: ptr = &dv1; //put address of dv1 in pointer
void show() ptr->show(); //execute show()
{ cout << “Derv1\n”; } ptr = &dv2; //put address of dv2 in pointer
}; ptr->show(); //execute show()
return 0;
}
Polymorphism- Virtual Member Functions Accessed with Pointers
• The output of this program is
Derv1
Derv2
• The rule is that the compiler selects the function based on the contents of the pointer ptr,
not on the type of the pointer
Polymorphism-Abstract Classes and Pure Virtual Functions
• When we will never want to instantiate objects of a base class, we call it an
abstract class.
• Such a class exists only to act as a parent of derived classes that will be used to
instantiate objects.
• It may also provide an interface for the class hierarchy.
• How can we make it clear to someone using our family of classes that we don’t
want anyone to instantiate objects of the base class?

• By placing at least one pure virtual function in the base class. A pure virtual
function is one with the expression =0 added to the declaration.

• The equal sign here has nothing to do with assignment; the value 0 is not
assigned to anything. The =0 syntax is simply how we tell the compiler that a
virtual function will be pure.
Polymorphism
#include <iostream> class Derv2 : public Base //derived class 2
using namespace std; {
public:
class Base //base class void show()
{ { cout << “Derv2\n”; }
public: };
virtual void show() = 0; //pure virtual function
}; int main()
{
class Derv1 : public Base //derived class 1 // Base bad; //can’t make object from abstract class
{ Base* arr[2]; //array of pointers to base class
public: Derv1 dv1; //object of derived class 1
void show() Derv2 dv2; //object of derived class 2
{ cout << “Derv1\n”; } arr[0] = &dv1; //put address of dv1 in array
}; arr[1] = &dv2; //put address of dv2 in array
arr[0]->show(); //execute show() in both objects
arr[1]->show();
return 0;
}
Polymorphism
• Now if in main() you attempt to create objects of class Base, the
compiler will complain that you’re trying to instantiate an object of an
abstract class. It will also tell you the name of the pure virtual
function that makes it an abstract class.

• Once you’ve placed a pure virtual function in the base class, you must
override it in all the derived classes from which you want to
instantiate objects. If a class doesn’t override the pure virtual
function, it becomes an abstract class itself, and you can’t instantiate
objects from it(although you might from classes derived from it).
Polymorphism- Virtual function Example
#include <iostream> class student : public person class professor : public person {
using namespace std; { private:
private: int numPubs; published
class person //person class float gpa; public:
{ public: void getData() {
protected: void getData() person::getName();
char name[40]; { cout << “ Enter number of professor’s
public: person::getName(); publications: “;
void getName() cout << “ Enter student’s GPA: “; cin >> numPubs;
{ cout << “ Enter name: “; cin >> gpa; }
cin >> name; } } bool isOutstanding()
void putName() bool isOutstanding() { return (numPubs > 100) ? true : false; }
{ cout << “Name is: “ << name << { return (gpa > 3.5) ? true : false; } };
endl; } };
virtual void getData() = 0; //pure virtual
func
virtual bool isOutstanding() = 0;
//pure virtual func
};
• The person class is an abstract class because it contains the pure virtual functions getData() and isOutstanding().
Polymorphism- Virtual function Example
int main() for(int j=0; j<n; j++) //print names of all
{ { //persons, and
person* persPtr[100]; //array of pointers to persons persPtr[j]->putName(); //say if outstanding
int n = 0; //number of persons on list if( persPtr[j]->isOutstanding() )
char choice; cout << “ This person is outstanding\n”;
}
do { return 0;
cout << “Enter student or professor (s/p): “; }
cin >> choice;
if(choice==’s’) //put new student
persPtr[n] = new student; // in array
else //put new professor
persPtr[n] = new professor; // in array
persPtr[n++]->getData(); //get data for person
cout << “ Enter another (y/n)? “; //do another person?
cin >> choice;
} while( choice==’y’ ); //cycle until not ‘y’
Polymorphism- Virtual function Example
Enter student or professor (s/p): s Enter student or professor (s/p): p
Enter name: Timmy Enter name: Shipley
Enter student’s GPA: 1.2 Enter number of professor’s publications: 714
Enter another (y/n)? y Enter another (y/n)? y

Enter student or professor (s/p): s Enter student or professor (s/p): p


Enter name: Brenda Enter name: Wainright
Enter student’s GPA: 3.9 Enter number of professor’s publications: 13
Enter another (y/n)? y
Enter another (y/n)? n
Enter student or professor (s/p): s Name is: Timmy
Enter name: Sandy Name is: Brenda
Enter student’s GPA: 2.4 This person is outstanding
Enter another (y/n)? y Name is: Sandy
Name is: Shipley
This person is outstanding
Name is: Wainright
Polymorphism-Virtual Base Classes

• Consider the situation shown in Figure, with a base class, Parent; two derived
classes,Child1 and Child2; and a fourth class, Grandchild, derived from both Child1 and
Child2.
• In this arrangement a problem can arise if a member function in the Grandchild class
wants to access data or functions in the Parent class
Polymorphism
// ambiguous reference to base class class Grandchild : public Child1, public Child2
class Parent {
{ public:
protected: int getdata()
int basedata; { return basedata; } // ERROR: ambiguous
}; };
class Child1 : public Parent
{ };
class Child2 : public Parent
{ };
• A compiler error occurs when the getdata() member function in Grandchild attempts to access
basedata in Parent.
• When the Child1 and Child2 classes are derived from Parent, each inherits a copy of Parent; this
copy is called a subobject.
• Each of the two subobjects contains its own copy of Parent’s data, including basedata.
• Now, when Grandchild refers to basedata, which of the two copies will it access? The situation is
ambiguous, and that’s what the compiler reports.
• To eliminate the ambiguity, we make Child1 and Child2 into virtual base classes,
• The use of the keyword virtual in these two classes causes them to
share a single common subobject of their base class Parent.
• Since there is only one copy of basedata, there is no ambiguity when
it is referred to in Grandchild.
• The need for virtual base classes may indicate a conceptual problem
with your use of multiple inheritance, so they should be used with
caution.
Friend Functions
• The concepts of encapsulation and data hiding dictate that
nonmember functions should not be able to access an object’s
private or protected data.
• The policy is, if you’re not a member, you can’t get in.
• However, there are situations where such rigid discrimination leads to
considerable inconvenience.
Scenario:
• Imagine that you want a function to operate on objects of two
different classes.
• Perhaps the function will take objects of the two classes as
arguments, and operate on their private data.

Solution?

• To solve this situation there’s friend function.


#include <iostream> int frifunc(alpha a, beta b) //function definition
using namespace std; {
return( a.data + b.data );
class beta; //needed for frifunc declaration }
class alpha
{ int main()
private: {
int data; alpha aa;
public: beta bb;
alpha() : data(3) { } //no-arg constructor cout << frifunc(aa, bb) << endl; //call the function
friend int frifunc(alpha, beta); //friend function return 0;
}; }
•The declaration of friend function can be placed anywhere in
class beta the class; it doesn’t matter whether it goes in the public or the
{ private section.
private:
int data; •A minor point: Remember that a class can’t be referred to until
public: it has been declared. Class beta is referred to in the declaration
beta() : data(7) { } //no-arg constructor of the function frifunc() in class alpha, so beta must be declared
friend int frifunc(alpha, beta); //friend function before alpha. Hence the declaration.
};
Polymorphism
Polymorphism
Polymorphism
Polymorphism
Polymorphism

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy