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

家住魔仙堡 提交于 2019-12-05 08:29:19

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.

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.

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.

The problem here seems very simple. CBase can not magically upgrade to CChild! Let me rewrite your example and add some comments. It should be self explanatory...

#include <iostream>

class CBase {
public:
    virtual void vfunc() { std::cout << "CBase::vfunc()" << std::endl; }
    virtual ~CBase(){} // Virtual destructor... extremely important! I'll let you figure out why as an excercise
};

class CChild: public CBase {
public:
    void vfunc() { std::cout << "CChild::vfunc()" << std::endl; }
    ~CChild(){} // Is this destructor called? When? Try adding some std::cout to each destructor
};

int main() 
{
    CBase *ptr1 = new CBase;
    CBase *ptr2 = new CChild;

    ptr1->vfunc(); // ptr1 points to an instance of CBase. This is what's important!!
    ptr2->vfunc(); // ptr2 points to an instance of CChild, which can be referenced to as a CBase

    delete ptr1;
    delete ptr2;
}

Output:

CBase::vfunc()
CChild::vfunc()

PS: I just realised I'm about 5 years late to the party, but since I find educational value on this I'll post it anyways!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!