Solved

Virtual functions with examples

Posted on 2003-12-08
6
568 Views
Last Modified: 2013-11-15
Hi experts,

Can someone explain to me clearly what Virtual functions are???
Suppose I have a simple class for a four function calculator as follows:

class calculator {
public:
virtual int add (int a, int b) { return a + b; }
virtual int sub (int a, int b) { return a - b; }
virtual int mul (int a, int b) { return a * b; }
virtual int div (int a, int b) { return a / b; }
};

Now I want to  derive a new class that adds memory to the class so that the result
of each calculation will be stored in that memory .

I also want the following functions to be part of the derived class:

int get_mem() and int clear_mem()

I would like to understand the concept of virtual functions..can someone guide me !

thanks

0
Comment
Question by:anushan
  • 3
  • 2
6 Comments
 
LVL 16

Expert Comment

by:imladris
ID: 9900232
In straight inheritance a virtual function will not provide any benefits. The benefits of virtual functions arrive when you are dealing with some number of objects, all of which have been derived from some common ancestor, and you want to treat them similarly.

The classic example is for a Shape class. Suppose one of the methods Shape provides is area(), and that there are two derived classes Square and Circle. The area function for Square is "return(width*height);". The area function for Circle is "return(pi*radius*radius);".

Now there is some other class, and all it knows is that it is dealing with an array of Shape classes.

Shape shparray[10];

Now how can it calculate the total area of all the shapes it has? If it calls area, which method will be called? A method defined in Shape? Or a method defined in the actual class? How will it know what code to jump to?

The correct answer to these questions lies in the use of virtual functions. A virtual function is "late-binding". That means that the class object itself has information about itself sufficient to resolve these questions. So when the areacalculating class calls:

total=shparray[0].area();

The executable is able to determine which area method to call. This kind of behaviour is also referred to as polymorphism. A situation in which a method call on an object will behave "appropriately" depending on the type of the object.

Note that for this to work, Shape must provide an area method. In this case it would probably be declared "pure virtual", that is, without any definition. But without that you would not be able to call the area method for Shape objects.

So, in the above example, where you are deriving a new calculator class with additional methods, there is no apparent way for this to be useful in and of itself. Unless there is some other class that wants to treat your new calculator as a regular calculator, and you can amend the regular calculator class to provide at least an interface to the new functionality, there will be no benefit.
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 9900302
To quote "C++ Primer, Third Edition" by Lippman et al.:
"When a member function is virtual, the function invoked is the one defined in the dynamic type of the class object (or pointer or reference) through which it is invoked."

A bit convoluted...What it means is that which version of a virtual member function depends on the dynamic type of the pointer or reference of the object on which you're trying to invoke the virtual member function....hmmm...that was convoluted too...Let's try an example!

class LoanType1
{
   public:
      virtual float calculateMonthlyAmount(float principal){ return principal * 0.1; }
}

class LoanType2 : LoanType1
{
      virtual float calculateMonthlyAmount(float principal){ return principal * 0.2/4; }
}

Say now that we have a reference to a LoanType2:
LoanType2 *myLoan2 = ...;
LoanType1 *myLoan1 = dynamic_cast<LoanType1*>myLoan2;
float amount2 = myLoan2->calculateMonthlyAmount(12);         // this amount will be calculated using the function declared in LoanType2!
float amount1 = myLoan1->calculateMonthlyAmount(12);         // this amount will be calculated using the function declared in LoanType1, even though the "real" type of the class is LoanType2!

So, amount2 != amount1 (unless the value of principal is 0) !

I hope this clarifies things!
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 9900309
imladris, sorry about the post. Your post wasn't there when I looked and started typing.
0
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 

Author Comment

by:anushan
ID: 9900626
thanks for explaining that to me.

Now I am sure that the example I posted doesn't utilize the concept of virtual functions well...but here's what I tried with it (just straight inheritence)......does this make sense??

#include <iostream>

using namespace std;

class calculator {
public:
virtual int add (int a, int b) { return a + b; }
virtual int sub (int a, int b) { return a - b; }
virtual int mul (int a, int b) { return a * b; }
virtual int div (int a, int b) { return a / b; }
};

class derived1 : public calculator {
private:
   int element;
public:
   int add (int a, int b) { return (element = a + b); }
   int sub (int a, int b) { return (element = a - b); }
   int mul (int a, int b) { return (element = a * b); }
   int div (int a, int b) { return (element = a / b); }
   int get_mem() { return element; }
   int clear_mem() { return (element = 0); }
};


calculator *bptr = new derived1;

int main()
{
  bptr->add(2, 3);
  cout << "Element is: " << ((derived1 *)bptr)->get_mem() << endl;
  bptr->mul(4, 5);
  ((derived1 *)bptr)->get_mem();
  ((derived1 *)bptr)-> clear_mem();
  return 0;
}
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 9900803
It does if you're trying to implement functionality equal to MR and MC on a calculator.
0
 
LVL 16

Accepted Solution

by:
imladris earned 200 total points
ID: 9904951
Yup, that's fine code.

In practical terms for that code as it stands, there is, of course, no real need to declare bptr to be calculator. All the casts could be removed, and the type checking would be stronger if you declared bptr to be what it is: derived1. Then you would get:

derived1 *bptr = new derived1;

int main()
{
  bptr->add(2, 3);
  cout << "Element is: " << bptr->get_mem() << endl;
  bptr->mul(4, 5);
  bptr->get_mem();
  bptr-> clear_mem();
  return 0;
}
0

Featured Post

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Replication has always been one of those technologies that people run scared from. The main reason is usually cost. When you think of replication, your mind drifts to solutions that replicate from one disk frame to another using block level technolo…
VM backups can be lost due to a number of reasons: accidental backup deletion, backup file corruption, disk failure, lost or stolen hardware, malicious attack, or due to some other undesired and unpredicted event. Thus, having more than one copy of …
This tutorial will walk an individual through the steps necessary to enable the VMware\Hyper-V licensed feature of Backup Exec 2012. In addition, how to add a VMware server and configure a backup job. The first step is to acquire the necessary licen…
This tutorial will walk an individual through the process of installing the necessary services and then configuring a Windows Server 2012 system as an iSCSI target. To install the necessary roles, go to Server Manager, and select Add Roles and Featu…

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now