Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call virtual function of derived class through base class pointer

Let's see this code:

class CBase
{
 public:
    virtual vfunc() { cout << "CBase::vfunc()" << endl; }
};

class CChild: public CBase
{
 public:
    vfunc() { cout << "CChild::vfunc()" << endl; }
};

int main() 
{
 CBase *pBase = new CBase;
 ((CChild*)pBase)->vfunc(); // !!! important 
 delete pBase;
 return 0;
}

The output is:

CBase::vfunc()

But I want to see: CChild::vfunc()

Explicit ((CChild*)pBase) casts to type "CChild*". So why to call derived vfunc() I need replace "important" string with: ((CChild*)pBase)->CChild::vfunc();

like image 483
LEXX Avatar asked Aug 10 '12 18:08

LEXX


People also ask

Can base class pointer be used to call virtual function?

A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.

How do you call a virtual function from a derived class?

A virtual function is a member function of a base class that is overridden by a derived class. When you use a pointer or a reference to the base class to refer to a derived class object, you can call a virtual function for that object and have it run the derived class's version of the function.

Can a base class pointer call methods in the derived class?

// As base-class pointer cannot access the derived class variable.

How do you find the virtual function in base class?

Virtual functions should be accessed using pointer or reference of base class type to achieve runtime polymorphism. The prototype of virtual functions should be the same in the base as well as derived class. They are always defined in the base class and overridden in a derived class.


3 Answers

That's not how it works - this is:

CBase *pBase = new CChild;
pBase->vfunc();

virtual function calls are resolved dynamically on pointers & references (unless you call the method explicitly, like you did). Which means it doesn't matter what you tell the compiler the pointer is, it will look for the method in the vftable. Which, in your case, is the vftable of CBase.

like image 81
Luchian Grigore Avatar answered Sep 24 '22 04:09

Luchian Grigore


You can't. *pBase is an object of type CBase. You cannot treat it as if it were a CChild because it isn't a CChild object.

Use of the pointer obtained by the cast to CChild* causes your program to exhibit undefined behavior.

like image 31
James McNellis Avatar answered Sep 24 '22 04:09

James McNellis


the other answers make important points -- to supplement: if you may in fact be dealing with a CChild (e.g. it is a reference passed as a parameter), then you can use dynamic_cast to downcast. however, high reliance on dynamic_cast is often an indication your design has gone wrong.

detail on the cast can be found here: http://msdn.microsoft.com/en-us/library/cby9kycs(v=vs.80).aspx

so the process would entail casting the CBase parameter to CChild via dynamic_cast, if the reference is a CChild and dynamic_cast succeeds, then you could be sure you are dealing with a CChild and you could then safely use it as a CChild.

like image 27
justin Avatar answered Sep 22 '22 04:09

justin