5

让我们看看这段代码:

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();

4

4 回答 4

6

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

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

virtual函数调用是在指针和引用上动态解析的(除非您像您一样显式调用该方法)。这意味着无论你告诉编译器指针是什么,它都会在 vftable 中查找方法。在您的情况下,哪个vftableCBase.

于 2012-08-10T18:47:38.933 回答
5

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

使用通过转换获得的指针CChild*会导致您的程序表现出未定义的行为。

于 2012-08-10T18:47:41.793 回答
2

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

可以在此处找到有关演员表的详细信息:http: //msdn.microsoft.com/en-us/library/cby9kycs (v=vs.80).aspx

因此该过程需要将CBase参数转换为CChildvia dynamic_cast,如果引用是 aCChild并且dynamic_cast成功,那么您可以确定您正在处理 aCChild并且您可以安全地将其用作 a CChild

于 2012-08-10T18:52:28.923 回答
1

这里的问题看起来很简单。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 年,但既然我发现这有教育价值,我还是会发布它!

于 2017-10-02T02:33:27.193 回答