C++ virtual functions

C++ virtual functions

As mentioned earlier, polymorphism refers to the property by which objects belonging to different classes are able to respond to the same message, but in different forms.
An essential requirement of the polymorphism is therefore the ability to refer to the objects without any regard to their classes . This necessary the use of a single pointer variable to refer to the objects of different classes.

Here we use the pointer to base(super) class to refer to all the derived objects. but we just discovered that a base pointer, even it is made to contain the address of a derived class, always executes the function in the base class.The compiler simply ignores the content.

how do we then achieve polymorphism? it is achieved using virtual function

When we use the same function name in both the base and derived classes.The function in base class in declared as virtual using keyword virtual preceding its normal declaration
when a function is made virtual, C++ language determines which function to use at run time based on the type of object pointed to by the base pointer, rather than the type of the pointer. This by making the base pointer to point to different objects, we can execute different version of virtual function

VIRTUAL FUNCTIONS

#include
<iostream >
using namespace std;
class Base
{
public:
void display()
{
cout << "\n display base";
}
virtual void show()
{
cout << "\n show base";
}
};
class derived: public Base
{
public:
void display()
{
cout << "\n Display Derived";
}
void show()
{
cout << "\n show derived";
}
};
int main()
{
Base B;
derived D;
Base *bptr;
cout << "\n bptr points to Base \n";
bptr=&B;
bptr->display(); // calls Base Version
bptr->show(); // calls derived version
cout << "\n \n bptr points to derived \n";
bptr=&D;
bptr->display(); // calls base version
bptr->show(); // calls derived version
}

output:
bptr points to Base
Display base
show base
bptr points to derived
Display base
show derived

when bptr is made to point to the object D, The statement
bptr->display();
calls only the function associated with the Base(Base::display()), whereas the statement
bptr->show();
calls thee derived version of show(). This is because the function display() has not been made virtual in the Base class one important point to remember is that, we must access virtual functions through the use of a pointer declared as pointer to the base class. here is question why cannot we use the object name (with the dot operator) the same way as any other member function to call the virtual function? we can but remember run time polymorphism is achieved only when a virtual function is accessed through a pointer to the base class.

Let us take an example where virtual function are implemented in practice. consider a books show which sells both books and video tapes. We can create a class known as media that stores the title and price of a publication. we can create a class known as media that stores the title and price of a publication
we can then create two derived class one for storing the number of pages in a book and another for storing the playing time of a type let is see class hierarchy for the book shop

The class are implemented in program A display() function is used in all the classes to display the contents of class .

Notice: The function display() has been declared virtual in media, the base class. In main program we create a heterogeneous list of pointer of type media as shown example in below

media *list[2];=
{
&book1; [1], &tape1
};

The base pointers list[0] and list[1] are initialized with the addresses of objects books=1 and tape1

RUNTIME POLYMORPHISM
#include <iostream>
#include <cstring>
class media
{
protected:
char title[50];
float price;
public:
media(char *s, float a)
{
strcpy(title,s);
price=a;
}
virtual void display()
{
// empty virtual function
} };
class book: public media
{
int pages; public:
book(char *s,float a, int p):media(s,a)
{
pages=p;
}
void display();
};
class tape: public media
{
float time;
public:
tape(char *s,float a,float t):media(s,a)
{
time=t;
}
void display();
};
void book::display()
{
std::cout << "\n title:" << title;
std::cout << "\n pages:" << pages;
std::cout <<"\n price:" << price;
}
void tape::display()
{
std::cout << "\n Title:" << title;
std::cout << "\n play time:" << time <<"mins";
std::cout << "\n price:" << price;
}
int main()
{
char *title=new char[30];
float price,time;
int pages;
// book details
std::cout << "\nEnter Books Details \n";
std::cout << "Title:";
std::cin >> title;
std::cout << "price:";
std::cin >> price;
std::cout << "pages:";
std::cin >> pages;
book book1(title,price,pages);
// Tape Details
std::cout << "\n Enter Tape Details\n";
std::cout << "Title:";
std::cin >> title;
std::cout << "price:";
std::cin >> price;
std::cout << "play time(mins):";
std::cin >> time;
tape tape1(title, price, time);
media* list[2];
list[0]=&book1;
list[1]=&tape1;
std::cout << "\n MEDIA DETAILS";
std::cout << "\n....... Book.........";
list[0]->display(); // display book details
std::cout << "\n....TAPE......";
list[1]->display(); // display tape details
}

Enter Books Details
Title:E Balaguruswami
price:99
pages:350
Enter Tape Details
Title:programming concepts
price:95
play time(mins):60
MEDIA DETAILS
……. Book………
title:E Balaguruswami
pages:99
price:350
….TAPE……
Title:programming concepts
play time:95
price:95

Rules for virtual functions

when virtual function are created for implementing late binding, we should observe some basic rules that satisfy the compiler requirements

1. The virtual function must be member of some class
2. They cannot be static members.
3. They are accessed by using object pointers.
4. A virtual function can be a friend of another class.
5. A virtual function in a base class must be defined, even through it may not be used.
6. The prototype of the base class version of a virtual function and all the derived class. versions must be identical. if two function with the same name have different prototypes, C++ consider them as overloaded functions, and the virtual function mechanism is ignored
7. we cannot have virtual constructors, but we can have virtual destructor.
8 while a base pointer can point to any type of the derived object, the reverse is not true. That is to say, we cannot use pointer to a derived class to access an object of the base type.
9. When a base pointer points to a derived class, incrementing or decrementing it will not make it to point to the next object of the derived class. it is incremented or decremented only relative to its base type. Therefore we should not use this method to move the pointer to the next object.
10. if a virtual function is defined in the base class, it need not be necessarily redefined in the derived class. In such cases call will invoke the base function.

  • C++ Dynamic Initialization of Objects
  • C++ Copy Constructor
  • C++ Dynamic Constructor
  • C++ Destructors
  • C++ Exercise
  • C++ Operator Overloading
  • C++ Overloading Unary Operators
  • Const pointer in C
  • Void pointer in c
  • C++ Overloading Binary Operators
  • C++ Overloading Binary Operators Using Friends
  • C++ Manipulation String Using Operators
  • C++ Rules for overloading operators
  • C++ Exercise
  • C++ Basic To class Type
  • C++ Class TO Basic Type
  • C++ One class To another class type
  • C++ Exercise
  • C++ Inheritance introduction
  • C++ Single Inheritance
  • C++ Multiple Inheritance
  • C++ Ambiguity Resolution in inheritance
  • C++ Hierarchical Inheritance
  • C++ Hybrid Inheritance
  • C++ Virtual Base Classes
  • C++ Exercise
  • C++ abstract class
  • C++ nesting of classes
  • C++ Exercise
  • C++ polymorphism
  • C++ Exercise
  • C++ pointers
  • C++ Pointers TO object
  • C++ this pointer
  • C++ Pointer to Derived class
  • C++ Virtual functions
  • C++ Exercise
  • C++ streams
  • C++ unformatted I/O operations
  • C++ Put() and get()
  • C++ getline() and write()
  • C++ Formatted console I/O
  • C++ Manipulators
  • C++ Exercise
  • C++ file handling
  • C++ file stream classes
  • C++ Open and closing file
  • C++ open using constructor
  • C++ open using open()
  • C++ Detecting End of file
  • C++ File modes
  • C++ File pointers and Manipulators
  • C++ Sequential I/O
  • C++ Reading and Writing
  • C++ Updating a File
  • C++ Error handling In File
  • C++ Command Line Arguments
  • C++ Exercise
  • C++ Template introduction
  • C++ Class Templates with multiple Parameters
  • C++ Function templates
  • C++ Function templates with multiple parameters
  • C++ member function Template
  • C++ Exercise
  • C++ Exception handling
  • C++ Basics of Exception Handling
  • C++ Exception Handling Mechanism
  • C++ Throwing Mechanism
  • C++ Catch Mechanism
  • C++ Catch all Exceptions
  • C++ Re-Throwing An Exception
  • C++ Specifying Exceptions
  • C++ Exercise