这个问题(非常常见)往往出现于这样的例子中:
#include<iostream>
using namespace std;
class B {
public:
int f(int i) { cout << "f(int): "; return i+1; }
// ...
};
class D : public B {
public:
double f(double d) { cout << "f(double): "; return d+1.3; }
// ...
};
int main()
{
D* pd = new D;
cout << pd->f(2) << '\n';
cout << pd->f(2.3) << '\n';
}
它输出的结果是:
f(double): 3.3
f(double): 3.6
而不是象有些人猜想的那样:
f(int): 3
f(double): 3.6
换句话说,在 B 和 D 之间并没有发生重载的解析。编译器在 D 的区域内寻找,找到了一个
函数double f(double),并执行了它。它永远不会涉及(被封装的)B的区域。在C++
中,没有跨越区域的重载——对于这条规则,继承类也不例外。更多的细节,参见《C++语
言的设计和演变》和《C++程序设计语言》。
但是,如果我需要在基类和继承类之间建立一组重载的 f()函数呢?很简单,使用 using
声明:
class D : public B {
public:
using B::f; // make every f from B available
double f(double d) { cout << "f(double): "; return d+1.3; }
// ...
};
进行这个修改之后,输出结果将是:
f(int): 3
f(double): 3.6
这样,在 B 的 f()和 D 的 f()之间,重载确实实现了,并且选择了一个最合适的 f()进行
调用。