内容思维导图
第8章 函数探幽
1. 内联函数
- 常规函数和内联函数的主要区别不在于编写方式,而在于C++编译器如何将它们组合到程序中。对于内联代码,程序无需跳到另一个位置处执行代码,然后再跳回来。因此,内联函数的运行速度比常规函数快。
- 使用内联函数必须采取下述措施之一:
- 在函数声明前加上关键字
inline
。
- 在函数定义前加上关键字
inline
。
// 内联函数定义
inline double square(double x) { return x * x; }
int main()
{
// 函数调用
}
2. 引用变量
int& refer = 6;
- 必须在声明引用时进行初始化,而不能像指针那样,先声明,再赋值。
// 下面的代码是错误的
int rat;
int& rodent;
rodent = rat;
- 引用经常被用作函数参数,使得函数中的变量名成为调用程序中的变量的别名,这种传递参数的方法称为按引用传递。
- 按引用传递与按值传递的外在区别是声明函数的方式:
void swapr(int& a, int& b); // 按引用传递
void swapv(int a, int b); // 按值传递
- 传递引用与传递指针的区别:
- 声明函数参数的方式。
- 指针版本在使用参数值需要使用解除引用操作符
*
。
-
const
引用参数创建临时变量的情形:
- 实参的类型正确,但不是左值(非左值:字面常量或多项表达式)。
- 实参的类型不正确,但可以转换为正确的类型。
- 将引用参数声明为常量数据的理由:
- 使用
const
可以避免无意中修改数据的编程错误。
- 使用
const
使函数能够处理const
和非const
实参,否则将只能接受非const
数据。
- 使用
const
引用使函数能够正确生成并使用临时变量。
-
记住:返回引用的函数实际上是被引用的变量的别名。
- 返回引用应注意的问题:应避免返回当函数终止时不再存在的内存单元引用。解决方法:
- 返回一个作为参数传递给函数的引用。
- 用
new
来分配新的存储空间(隐藏new
调用,应注意使用delete
来释放)。
- 将
const
用于引用的返回类型,只意味着你不能使用返回的引用来直接修改它指向的值。
- 使用引用参数的两个主要原因:
- 程序员能够修改调用函数中的数据对象。
- 提高程序运行速度。
- 函数传递类型选择的指导原则:
- 数据对象很小,则按值传递。
- 数据对象是数组,则使用指针,并将指针声明为指向
const
的指针。
- 数据对象是较大的结构,则使用
const
指针或const
引用。
- 数据对象是类对象,则使用
const
引用。传递类对象参数的标准方式是按引用传递。
3. 默认参数
- 默认参数指的是当函数调用中省略了实参时自动使用的一个值。
char* left(const char* str, int n = 1); // 参数n默认值为1
int chico(int n, int m = 6, int j); // 错误!!!
- 只有原型指定了默认值,函数定义与没有默认参数时完全相同。
4. 函数重载
- 术语多态(polymorphism) 指的是多种形式,因此函数多态允许函数可以有多种形式。术语函数重载(function overloading) 指的是可以有多个同名的函数,因此对名称进行了重载。两个术语指的是同一回事。
- 函数重载的关键是函数的参数列表——也称为函数特征标(function signature)。
- 编译器在检查函数特征标时,将类型引用和类型本身视为同一个特征标。
5. 函数模板
- C++模板函数具体化方法:
- 对于给定的函数名,可以有非模板函数、模板函数和显式具体化模板函数以及它们的重载版本。
- 显式具体化的原型和定义应以
template<>
打头,并通过名称来指出类型。
- 具体化将覆盖常规模板,而非模板函数将覆盖具体化和常规模板。
// 非模板函数
void Swap(job&, job&);
// 模板函数原型(其中class可以改用关键字typename)
template<class Any>
void Swap(Any&, Any&);
// 显式具体化模板函数
template<> void Swap<job>(job&, job&);
template<> void Swap(job&, job&); // 简化形式
实参 |
形参 |
Type |
Type& |
Type& |
Type |
Type[] |
*Type |
Type(argument-list) |
Type(*)(argument-list) |
Type |
const Type |
Type |
volatile Type |
Type* |
const Type |
Type* |
volatile Type* |
// 下面的原型都是完全匹配的
void recycle(blot);
void recycle(const blot);
void recycle(blot&);
void recycle(const blot&);
- 术语最具体(most specialized) 并不一定意味着显式具体化,而是指编译器腿短使用哪种类型时执行的转换最少。
- 用于找出最具体的模板的规则被称为函数模板的部分排序规则(partial ordering rules)。
网友评论