C++ 派生类中的虚函数隐藏

C++ 派生类中的虚函数隐藏,c++,overloading,overriding,C++,Overloading,Overriding,我有两个与继承相关的类:- 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 { p

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

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;
    }
};
但我无法得到最后一种情况的澄清

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

编译器不会使用vtables和vptrs将此调用绑定到f的派生版本。但它却在做别的事情。有人能给我提供编译器如何根据语言机制尝试解决此调用的完整路径。

vtable仅在运行时输入图片。生成的程序集将查找函数的vptr值并跳转到该地址。这也意味着多态性被“限制”到
Base
知道的函数。请注意,这也是更有意义的——类的定义应该只依赖于它自己和它的父类。如果您想让
Base*b
了解由
派生的
实现的虚拟函数,那么最终会得到
Base
s中的vtable条目数,这取决于它的子项。

vtable只在运行时进入图片。生成的程序集将查找函数的vptr值并跳转到该地址。这也意味着多态性被“限制”到
Base
知道的函数。请注意,这也是更有意义的——类的定义应该只依赖于它自己和它的父类。如果您想让
Base*b
了解由
派生的
实现的虚拟函数,那么最终会得到
Base
s中的vtable条目数,这取决于它的子项。

vtable只在运行时进入图片。生成的程序集将查找函数的vptr值并跳转到该地址。这也意味着多态性被“限制”到
Base
知道的函数。请注意,这也是更有意义的——类的定义应该只依赖于它自己和它的父类。如果您想让
Base*b
了解由
派生的
实现的虚拟函数,那么最终会得到
Base
s中的vtable条目数,这取决于它的子项。

vtable只在运行时进入图片。生成的程序集将查找函数的vptr值并跳转到该地址。这也意味着多态性被“限制”到
Base
知道的函数。请注意,这也是更有意义的——类的定义应该只依赖于它自己和它的父类。如果您想让
Base*b
知道由
派生的
实现的虚拟函数,那么最终会得到
Base
中的vtable条目的数量,这取决于它的子项。

如果指针的类型是
Base*
,那么您只能“查看”在类
Base
中定义的成员。编译器不(或假装不)“知道”变量是否真的指向
派生的
实例,即使您在前一行中刚刚为其分配了一个实例


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

如果指针的类型为
Base*
,则只能“查看”在class
Base
中定义的成员。编译器不(或假装不)“知道”变量是否真的指向
派生的
实例,即使您在前一行中刚刚为其分配了一个实例


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

如果指针的类型为
Base*
,则只能“查看”在class
Base
中定义的成员。编译器不(或假装不)“知道”变量是否真的指向
派生的
实例,即使您在前一行中刚刚为其分配了一个实例


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

如果指针的类型为
Base*
,则只能“查看”在class
Base
中定义的成员。编译器不(或假装不)“知道”变量是否真的指向
派生的
实例,即使您在前一行中刚刚为其分配了一个实例


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

编译器如何解决这种情况,是名称查找将首先选择一个类。若选择了Base,那个么将只使用基类中可用的函数。若选择了“派生”,并且可以从派生类中找到f,那个么就永远找不到基函数。因此,这实际上取决于指针的类型,以及可以使用的函数集。编译器如何解决这种情况,是名称查找将首先选择一个类。如果选择了Base,则只有Base cl中可用的函数
Base *b = new Derived;
b->f(str);     //results in error.