高质量C++/C 编程指南,v 1.0
# include
8.2 成员函数的重载、覆盖与隐藏
8.2.1 重载与覆盖
成员函数被重载的特征: (1)相同的范围(在同一个类中); (2)函数名字相同; (3)参数不同;
(4)virtual关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类); (2)函数名字相同;
2001
Page 49 of 87
// 函数声明 void output( float x); // 函数声明 cout << \ cout << \ int x = 1; float y = 1.0; output(x); output(y); output(1); // output int 1 // output float 1 // output int 1 output(0.5); // error! ambiguous call, 因为自动类型转换 output(int(0.5)); // output int 0 output(float(0.5)); // output float 0.5 成员函数的重载、覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚概
念,否则错误将防不胜防。
高质量C++/C 编程指南,v 1.0
(3)参数相同;
(4)基类函数必须有virtual关键字。 #include
本来仅仅区别重载与覆盖并不算困难,但是C++的隐藏规则使问题复杂性陡然增加。8.2.2 令人迷惑的隐藏规则
这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
示例程序8-2-2(a)中:
(1)函数Derived::f(float)覆盖了Base::f(float)。
(2)函数Derived::g(int)隐藏了Base::g(float),而不是重载。
2001
Page 50 of 87
示例8-2-1中,函数Base::f(int)与Base::f(float)相互重载,而Base::g(void)被
Derived::g(void)覆盖。
class Base void f(int x){ cout << \\void f(float x){ cout << \\ virtual void g(void){ cout << \class Derived : public Base virtual void g(void){ cout << \void main(void) { Derived d; Base *pb = &d; pb->f(42); pb->g(); // Base::f(int) 42 pb->f(3.14f); // Base::f(float) 3.14 // Derived::g(void)