隐藏在派生类中的虚函数

时间:2014-12-16 05:44:32

标签: c++ overloading override

我有两个与继承相关的类: -

class Base
{
public:
    virtual void f(int x)
    {
        cout << "BASE::int" << endl;
    }
    virtual void f(double x)
    {
        cout << "BASE::double" << endl;
    }
};

class Derived : public Base
{
public:
    virtual void f(str::string s)
    {
        cout << "DERIVED::string" << endl;
    }
};

我在派生类中使用不同的参数提供了相同的方法。这意味着而不是重写我隐藏了这个函数的基类版本。因此,以下电话预计对我来说很清楚。

std::string str("Hello");
Base b;
b.f(1);        //calls base class version.
b.f(str);      //error.

Derived d;
d.f(1);        //error.
d.f(str);      //calls derived class version.

但我无法澄清这最后一​​种情况。

Base *b = new Derived;
b->f(str);     //results in error.

编译器是否会使用vtable和vptrs将此调用绑定到f的派生版本。但相反,它正在做其他事情。任何人都可以提供完整的路径,编译器将如何根据语言机制尝试解析此调用。

2 个答案:

答案 0 :(得分:2)

如果您的指针属于Base*类型,那么您只能&#34;看到&#34;在课程Base中定义的成员。编译器没有(或假装没有)&#34;知道&#34;该变量确实指向Derived的实例,即使您刚刚在上一行中为其分配了一个。

当您将变量声明为Base*类型时,您需要告诉编译器:将其视为可以指向Base任何类从中衍生出来。因此,您无法访问在特定派生类中定义的成员,因为无法保证指针实际指向该派生类的实例。

答案 1 :(得分:1)

vtable仅在运行时进入图片。生成的程序集将查找函数的vptr值并跳转到该地址。这也意味着多态性受到限制&#34;到Base知道的函数。请注意,这也是更有意义的 - 类的定义应仅依赖于自身及其父级。如果您想让Base* b了解Derived实施的虚拟功能,您最终会得到Base中vtable条目的数量,具体取决于其子项。