如何通过基类指针调用派生类的虚函数(How to call virtual function of

2019-09-21 03:11发布

让我们来看看下面的代码:

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;
}

输出是:

CBase::vfunc()

但我想看看:CChild :: vfunc()

显式((CChild *)PBASE)强制转换成键入 “CChild *”。 那么,为什么叫得出vfunc()我需要更换为 “重要” 的字符串:((CChild *)PBASE) - > CChild :: vfunc();

Answer 1:

这不是它的工作原理 - 这就是:

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

virtual函数调用的指针和引用动态解析(除非你明确地调用该方法,像你这样)。 这意味着它并不重要,你分不清什么编译器的指针,它会寻找在vftable的方法。 其中,在你的情况,是vftableCBase



Answer 2:

你不能。 *pBase是类型的对象CBase 。 你不能把它当作好像它是一个CChild ,因为它不是一个CChild对象。

通过投所获得的指针使用CChild*使你的程序出现不确定的行为。



Answer 3:

其他答案作出重要点-补充:如果你实际上可能有要处理CChild (例如,它是作为参数传递的引用),那么你可以使用dynamic_cast向下转型。 然而,在高度依赖dynamic_cast通常表明你的设计出了问题。

上投细节可以在这里找到: http://msdn.microsoft.com/en-us/library/cby9kycs(v=vs.80).aspx

所以这个过程将需要铸造CBase参数CChild通过dynamic_cast ,如果引用是CChilddynamic_cast成功,那么你可以确保你正在处理一个CChild ,然后就可以放心地使用它作为一个CChild



Answer 4:

这里的问题似乎很简单。 CBase类不能神奇地升级到CChild! 让我重写你的榜样,并添加一些评论。 这应该是不言而喻的......

#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;
}

输出:

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

PS:我才意识到我是5年左右迟到了,但因为我对这个发现教育价值,我会反正它张贴!



文章来源: How to call virtual function of derived class through base class pointer