background image

C++/C 编程指南

—C++函数的高级特性

第 8

 

章 C++函数的高级特性

对比于 C 语言的函数,C++增加了重载(overloaded)、内联(inline)、const 和 virtual 四种
新机制。其中重载和内联机制既可用于全局函数也可用于类的成员函数,const 与 virtual

 

机制仅用于类的成员函数。
重载和内联肯定有其好处才会被 C++语言采纳,但是不可以当成免费的午餐而滥用。本章
将探究重载和内联的优点与局限性,说明什么情况下应该采用、不该采用以及要警惕错用。
8.1 函数重载的概念
8.1.1 重载的起源
自然语言中,一个词可以有许多不同的含义,即该词被重载了。人们可以通过上下文来判

断该词到底是哪种含义。 词的重载 可以使语言更加简练。例如 吃饭 的含义十分广泛,
人们没有必要每次非得说清楚具体吃什么不可。别迂腐得象孔已己,说茴香豆的茴字有四
种写法。
在 C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,即函数重载。这样
便于记忆,提高了函数的易用性,这是 C++语言采用重载机制的一个理由。例如示例 8-1-
1 中的函数 EatBeef,EatFish,EatChicken 可以用同一个函数名 Eat 表示,用不同类型的参数
加以区别。
void EatBeef(…); // 

 

可以改为 void Eat(Beef …);

void EatFish(…); // 

 

可以改为 void Eat(Fish …);

void EatChicken(…); // 

 

可以改为 void Eat(Chicken …);

示例 8-1-1 重载函数 Eat
C++语言采用重载机制的另一个理由是:类的构造函数需要重载机制。因为 C++规定构造
函数与类同名(请参见第 9 章),构造函数只能有一个名字。如果想用几种不同的方法创
建对象该怎么办?别无选择,只能用重载机制来实现。所以类可以有多个同名的构造函数。
8.1.2 重载是如何实现的?
几个同名的重载函数仍然是不同的函数,它们是如何区分的呢?我们自然想到函数接口
的两个要素:参数与返回值。
如果同名函数的参数不同(包括类型、顺序不同),那么容易区别出它们是不同的函数。
如果同名函数仅仅是返回值类型不同,有时可以区分,有时却不能。例如:
void Function(void);
int Function (void);
上述两个函数,第一个没有返回值,第二个的返回值是 int 类型。如果这样调用函数:
int x = Function ();
则可以判断出 Function 是第二个函数。问题是在 C++/C 程序中,我们可以忽略函数的返回
值。在这种情况下,编译器和程序员都不知道哪个 Function 函数被调用。
所以只能靠参数而不能靠返回值类型的不同来区分重载函数。编译器根据参数为每个重载
函 数 产 生 不 同 的 内 部 标 识 符 。 例 如 编 译 器 为 示 例 8-1-1 中 的 三 个 Eat 函 数 产 生 象
_eat_beef、_eat_fish、_eat_chicken 之类的内部标识符(不同的编译器可能产生不同风格的
内部标识符)。
如果 C++程序要调用已经被编译后的 C 函数,该怎么办?
假设某个 C 函数的声明如下: