|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionA few days back, I was doing a job, and unintentionally, I made a mistake in the code (What mistake? That I will explain in the detailed section of the article), and when I was caught by a bug and started de-bugging it, I was amazed how a little mistake can give a programmer a whole lot of pain. Yes, I made a mistake in the virtual function area. How? Let's find out........ Using the codeSo, why do we need a virtual function? Everyone knows that. Let's say I have a base class and a few derived class as well; and all the derived classes shares a common function, and in the driver program, I do not want to make a big huge #include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
class CommunicationDevices
{
//Base class has some property, for this article I dont need those
public:
inline virtual void which(){
cout<<"This is a common device..."<<endl;
}
};
class MobilePhoneWithGSMSupport:public CommunicationDevices
{
//Derived class also has some extended property, GSM related
public:
inline virtual void which(){
cout<<"This is a Mobile Phone...GSM Supported"<<endl;
}
};
class MobilePhoneWithCDMASupport:public CommunicationDevices
{
//Derived class also has some extended property, CDMA related
public:
inline void which(){
cout<<"This is a Mobile Phone....CDMA Supported"<<endl;
}
};
class Landline:public CommunicationDevices
{
//Derived class also has some extended property
public:
inline void which(){
cout<<"This is a Landline Phone..."<<endl;
}
};
class Iphone:public MobilePhoneWithGSMSupport
{
//More specific IPhone Feature here
public:
inline void which(){
cout<<"This is apple Iphone with AT&T connection, GSM Support only..."
<<endl;
}
};
void whichPhoneUserIsUsing(CommunicationDevices &devices){
devices.which();
}
int main(){
MobilePhoneWithGSMSupport user1;
MobilePhoneWithCDMASupport user2;
Landline user3;
Iphone user4;
whichPhoneUserIsUsing(user1);
whichPhoneUserIsUsing(user2);
whichPhoneUserIsUsing(user3);
whichPhoneUserIsUsing(user4);
return 0;
}
Here, the idea is simple. Since we are using a virtual function in the base class, the “ bash-3.2$ g++ -g -o hello code1.cpp
bash-3.2$ ./hello
This is a Mobile Phone...GSM Supported
This is a Mobile Phone....CDMA Supported
This is a Landline Phone...
This is apple Iphone with AT&T connection, GSM Support only...
Now, consider the following code, only a single character (believe me, just a single character) has been changed here from the previous code: We just modified our method #include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
class CommunicationDevices
{
//Base class has some property, for this article I dont need those
public:
inline virtual void which(){
cout<<"This is a common device..."<<endl;
}
};
class MobilePhoneWithGSMSupport:public CommunicationDevices
{
//Derived class also has some extended property, GSM related
public:
inline virtual void which(){
cout<<"This is a Mobile Phone...GSM Supported"<<endl;
}
};
class MobilePhoneWithCDMASupport:public CommunicationDevices
{
//Derived class also has some extended property, CDMA related
public:
inline void which(){
cout<<"This is a Mobile Phone....CDMA Supported"<<endl;
}
};
class Landline:public CommunicationDevices
{
//Derived class also has some extended property
public:
inline void which(){
cout<<"This is a Landline Phone..."<<endl;
}
};
class Iphone:public MobilePhoneWithGSMSupport
{
//More specific IPhone Feature here
public:
inline void which(){
cout<<"This is apple Iphone with AT&T connection, GSM Support only..."
<<endl;
}
};
void whichPhoneUserIsUsing(CommunicationDevices devices){
devices.which();
}
int main(){
MobilePhoneWithGSMSupport user1;
MobilePhoneWithCDMASupport user2;
Landline user3;
Iphone user4;
whichPhoneUserIsUsing(user1);
whichPhoneUserIsUsing(user2);
whichPhoneUserIsUsing(user3);
whichPhoneUserIsUsing(user4);
return 0;
}
We just modified our method void whichPhoneUserIsUsing(CommunicationDevices devices){
devices.which();
}
and bang.................given below is the output: bash-3.2$ g++ -g -o hello code2.cpp
bash-3.2$ ./hello
This is a common device...
This is a common device...
This is a common device...
This is a common device...
bash-3.2$ vim code2.cpp
So, what gets wrong here? Yes, you guessed it correctly, it's a famous copy-constructor problem. When the arguments are just a “ Hey Mr. Programmer, I am bound to create only a temporary object for this function ( This famous property is called Object Bisection, or Object Slicing. Cutting down the desired property from one object and copying it to a concrete base class object. References:
|
||||||||||||||||||||||