#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);
不按预期编译。
答案 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;
}
};