高质量C++编程_第8章_C++函数的高级特性(1)

1、函数重载

注意

(1) 函数重载只能靠参数 (参数类型 和 个数) 来区分,之后编译器根据参数为每个重载函数产生不同的内部标识符,调用函数时,可以根据内部标识符来找到函数的入口地址

一个函数的标识符包括:函数名、函数参数数量 及 类型信息

void foo( int x, int y ) 

标识符:_foo_int_float。

void foo( int x, float y )

标识符:_foo_int_int

(2) 函数重载的函数们必须在同一个作用域中,即是在同一个类中

(3) 无论参数是否相等,全局函数和类的成员函数同名不算重载,因为函数的作用域不同

(4) 不同的编译器可能产生不同风格的内部标识符,C++提供了符号extern“C”来兼容C中的函数 和 头文件

如果C++程序要调用已经被编译后的C 函数,可以使用符号extern“C”来解决这个问题

extern “C”
{
        void foo(int x, int y);

        // 其它函数
}

2、参数的缺省值
(1)  参数缺省值只能出现在函数的声明中,而不能出现在定义体中。

void Foo(int x=0, int y=0); // 正确,缺省值出现在函数的声明中

void Foo(int x, int y) // 缺省值不出现在函数的定义体中
{
        //函数定义
}

(2) 如果函数有多个参数,参数只能从后向前挨个儿缺省

void Foo(int x, int y=0, int z=0);

2、内联函数

(1) 用内联取代宏代码

目的:为了提高函数的执行速度

在C 程序中,可以用宏代码提高执行效率。宏代码本身不是函数,但使用起来象函数。

预处理器用复制宏代码的方式代替函数调用,省去了参数压栈、生成汇编语言的CALL调用、返回参数、执行return 等过程,从而提高了速度。

使用宏代码最大的缺点是容易出错,预处理器在复制宏代码时常常产生意想不到的边际效应。

这个过程与预处理有显著的不同,因为预处理器不能进行类型安全检查,或者进行自动类型转换

内联函数工作过程:

对于任何内联函数,编译器在符号表里放入函数的声明(包括名字、参数类型、返回值类型)。

如果编译器没有发现内联函数存在错误,那么该函数的代码也被放入符号表里。

在调用一个内联函数时,编译器首先检查调用是否正确(进行类型安全检查,或者进行自动类型转换,当然对所有的函数都一样)。

如果正确,内联函数的代码就会直接替换函数调用,于是省去了函数调用的开销。

假如内联函数是成员函数,对象的地址(this)会被放在合适的地方,这也是预处理器办不到的。

即,C++ 语言的函数内联机制既具备宏代码的效率,又增加了安全性,而且可以自由操作类的数据成员。

函数内联语法:

关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。
 
void Foo(int x, int y);

inline void Foo(int x, int y)
{
      
} 

即,inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”

注意:

(1) 定义在类声明之中的成员函数将自动地成为内联函数

(2) 内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率

如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间

3、不能使用内联的情况

(1) 如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。

(2) 如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值