重载虚函数并通过指向基类调用派生函数

时间:2015-02-14 10:36:14

标签: c++ inheritance overloading

#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("StackOverflow");
    Derived d;
    Base* b = &d;
    //calling derived::function() and function(s)    
    b->function();
    b->function(s);
}

由于超载,名称隐藏在派生类中出现 由于运行时关键字虚拟,因此应调用Derived :: function()。

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

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

不按预期编译。

2 个答案:

答案 0 :(得分:3)

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

名称隐藏发生在名称查找期间,即在重载之前 分辨率,也只涉及静态类型;在表达中 如b->function()b->function( s ),编译器会忽略 完全Derived;它在静态类型上进行名称查找。名称 隐藏只会考虑静态类型 Derived;一旦编译器在function中找到Derived,它就会 不要再看了。

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

答案 1 :(得分:2)

派生类中没有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;
    }
};