C++ primer plus 第8章 函数探幽

来源:互联网 发布:return of the mac 编辑:程序博客网 时间:2024/05/29 05:01
1. 内联函数
函数定义前加上关键字inline
通常省略原型,将整个定义放在本应提供原型的地方
  • 内联与宏
内联通过传递参数实现,如参数为4.5+5.5,那么传递的参数为12
宏通过文本替换实现
#define SQUARE(X) X*X
inline int square(int x) {return x*x;}

int main()
{
int a =  1;
int b = 1;

int a_define = SQUARE(a++);
int b_inline = square(b++);

cout << "define: " << a_define << endl;
cout << "inline: " << b_inline << endl;

cout <<"a = " << a <<"\n" <<"b = " << b << "\n";
system("pause");
        return 0;
}

输出:
define: 1
inline: 1
a = 3
b = 2

2. 引用变量
int a;
int  & a_alias = a;
int &表示指向int的引用,a和a_alias指向相同的值和内存单元
  • 引用和指针的区别
(1). 必须在声明引用时进行初始化
(2). 不能通过赋值来设置引用
(3). 传递引用并且不想修改信息时,使用常量引用 double refcube(const double &ra)
(4). 临时变量、引用参数和const
左值参数:可被引用的数据对象,例如变量、数组元素、结构成员、引用和被解除引用的指针
非左值: 字面常量、包含多项的表达式
仅当引用参数为const引用时,如果实参与引用参数不匹配,C++将生成临时变量:
1)实参类型正确,但不是左值
2)实参类型不正确,但可以转换为正确的类型
double refcube(const double &ra){ };

long edge = 5L;

refcube( edge );
refcube( side+10.0 );
编译器将生成一个临时的匿名变量,让ra引用它,这些临时变量只在函数调用期间存在。
对于形参为const引用的C++函数,如果实参不匹配,则其行为类似于按值传递,为确保原始数据不被修改,将使用临时变量来存储值。

如果接受引用参数的函数的意图不是修改作为参数传递的变量,那么应尽可能使用const:
  • 可以避免无意中修改数据的编程错误
  • 能够处理const和非const实参,否则只能接受非const实参
  • 使用const引用能够正确生成并使用临时变量
(5). 仅当C++函数返回变量的引用时,才可以将值(包括结构和类对象)赋给它,在这种情况下,值将被赋给被引用的变量或数据对象

使用传递的值而不做修改:
  • 数据对象很小则按值传递
  • 数组,则只能使用const指针
  • 数据对象是较大的结构,则使用const指针或const引用
  • 数据对象是类对象,则使用const引用
修改调用函数中的数据:
  • 内置数据类型,使用指针
  • 数据对象是数组,则只能使用指针
  • 数据对象是结构,则使用引用或指针
  • 数据对象是类对象,则使用引用

3. 默认参数
要为某个参数设置默认值,则必须为它右边的所有参数提供默认值
实参要按从左到右的顺序依次被赋给相应的形参而不能跳过任何参数
只有原型需要指定默认值,函数定义不需要

4. 函数重载 = 函数多态
  • 类型引用和类型本省是相同的参数类型,如
double cube (double x);
double cube (double &x);
当传入x时,编译器不知道选择哪个,所以不算重载
  • 匹配函数时并不区分const和非const变量
计算整数位数:除10
  • C++对函数的名称修饰或名称矫正
C++编译器根据函数原型中的形参类型对每个函数名进行加密,将名称转换为内部表示

5. 函数模板
在代码中包含模板本省并不会生成函数定义,编译器使用模板为特定类型生成函数定义时,得到的是模板实例
  • 模板函数声明:
template <class(或typename) Any>
void Function(Any a,Any b,……);
定义:
template <class(或typename) Any>
void Function(Any a,Any b,……){  ……  };
函数模板不能缩短可执行程序,编译器产生的最终代码将根据程序中的n个不同类型产生n的独立的函数定义,但是函数模板的好处是使生成多个函数定义更简单可靠。

  • 模板重载
参数列表不同的模板可以重载
  • 显示具体化
1)对于给定的函数名,可以有下列三种模式:
void function(type, type); //非模板函数

template <class T>
void function(T, T);  //模板函数

template <>
void function<type(可选)>(type, type); //显示具体化模板函数
优先级: 非模板函数 > 显示具体化模板函数 > 模板函数

  • 实例化和具体化
1) 允许显式实例化
template void function<type> (type, type,……)编译器将使用function模板生成一个type类型的实例
与集体化的区别是具体化意味着不使用function模板而独立定义




原创粉丝点击