高质量c编程规范 下载本文

高质量C++/C 编程指南,v 1.0

# include void output( int x); void output( int x) { } void output( float x) { } void main(void) { // } 示例8-1-3 隐式类型转换导致重载函数产生二义性

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 { public: }; { public: }; } 示例8-2-1成员函数的重载和覆盖

本来仅仅区别重载与覆盖并不算困难,但是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)