#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.3f(double): 3.6而不是某些人(錯誤地)猜想的那樣:f(int): 3
f(double): 3.6
換句話說,在D和B之間沒有重載發生。你調用了pd->f(),編譯器就在D的名字域里找啊找,找到double f(double)后就調用它了。編譯器懶得再到B的名字域里去看看有沒有哪個函數更符合要求。記住,在C++中,沒有跨域重載——繼承類和基類雖然關系很親密,但也不能壞了這條規矩。詳見《The Design and Evolution of C++》或者《The C++ Programming Language》第三版。
不過,如果你非得要跨域重載,也不是沒有變通的方法——你就把那些函數弄到同一個域里來好了。使用一個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 重載發生了——因為D中的那句 using B::f 明確告訴編譯器,要把B域中的f引入當前域,請 編譯器“一視同仁”。