虚函数,它们如何工作?

时间:2014-01-08 09:02:35

标签: c++ pointers inheritance virtual-functions

在C ++中,我无法理解,当基类指针存储派生类对象的地址时,它无法调用派生类成员函数?

#include <iostream>
using namespace std;

class Base
{
public:
    virtual void show()
    {
        cout<<" In Base ";
    }
};

class Derived: public Base
{
public:
    int x;
    void show()
    {
        cout<<"In Derived ";
    }
    Derived()
    {
        x = 10;
    }
};

int main(void)
{
    Base *bp, b;
    Derived d;
    bp = &d;
    bp->show();
    cout << bp->x;  
    return 0;
}

据我说: derived d =&gt;将内存分配给此对象(因此也为x),在地址200处说,  bp = &d; =&gt;它将地址200分配给bp。现在它应该可以调用bp-&gt; x? 但它给出了错误。

4 个答案:

答案 0 :(得分:2)

bp->x会出错,因为bp是指向Base类型对象的指针,而Base没有名为x的变量,只有Derived

如果x已移至Base,则BaseDerived可以访问{{1}},如果它是公开的或受保护的。

答案 1 :(得分:2)

名称的绑定在运行时发生。所以在编译时,bp是base类型。所以编译器对派生类型赋值一无所知。所以它说没有在基数中称为x的变量。

这就是虚拟功能的概念出现的地方。但嘿只是为了函数而不是变量。

答案 2 :(得分:1)

  

在C ++中,当基类指针存储时,我无法理解   它无法调用派生类的派生类对象的地址   类成员变量

是的,你可以,你只需要将指针强制转换为存在成员变量的类

cout << dynamic_cast<Derived*>(bp)->x;

答案 3 :(得分:0)

  

为什么bp-&gt; x是错误的?

因为在编译时,编译器无法分辨它指向的内容。如果实际上是,指向基类的指针怎么办?然后,x将完全不存在于基础对象中......

回答标题问题:当你有一个指向实际指向派生类实例的基类的指针时,然后调用声明为虚拟的公共函数在派生类中重新实现的基类将最终成为对该函数的派生类实现的调用(涉及的子集,私有/公共访问和名称隐藏可能会干扰,但这大致是如何运作的。)