重载虚函数并通过指向基的指针调用派生函数 class

overloading virtual function and calling derived function by pointer to base class

#include <bits/stdc++.h>
using namespace std;

class Base {
  public:
  virtual int function() const {
    cout << "Base::function()\n";
    return 1;
  }
  virtual void function(string) const {}
};


class Derived : public Base {
  public:
       // overloading function() of base
       int function(int) const {
         cout << "Derived::function()\n";
         return 4;
    }
};


int main()
{
    string s("Whosebug");
    Derived d;
    Base* b = &d;
    //calling derived::function() and function(s)    
    b->function();
    b->function(s);
}

由于重载,名称隐藏出现在派生class。
由于关键字 virtual 在运行时应调用 Derived::function()。

但是代码编译成功。 link : http://ideone.com/fbVm0P
这种奇怪行为的原因是什么?
编辑 1:

d.function();  
d.function(s);  

如预期的那样没有编译。

导出的class中没有int function() const

使用 override 关键字来避免这样的意外,即

class Derived
    : public Base
{
public:
    // not overriding function() of base
    auto function(int) const
        -> int override // This won't compile, because it doesn't override.
    {
         cout << "Derived::function()\n";
         return 4;
    }
};

重载解析使用静态类型(不是说它会 这里的区别)。所以 b->function()b->function( s ) 解析为 Base::function,没有错误。最后,由于这些 函数已声明 virtual,最终解决方案将采用 考虑派生 class 中的任何重载。但是没有,所以 将调用基 class 中的函数。

名称隐藏发生在名称查找期间,即重载之前 分辨率,也只关注静态类型;在一个表达式中 像 b->function()b->function( s ),编译器会忽略 Derived 完全;它对静态类型进行名称查找。姓名 隐藏只会考虑是静态类型 Derived;一旦编译器在 Derived 中找到 function,它就会 别再看了。

全局规则相当简单:名称查找(使用静态类型), 然后重载解析(使用静态类型),最后,如果 resolved name是一个虚函数,实际动态确定 功能取决于动态类型。