• 【c++】缺省值、内联函数与常成员函数


    目录

    一、用内联函数取代宏代码

    二、内联函数和宏定义的区别

    三、内联函数的编程风格

    四、内联函数的分类

    五、不适用使用内联的情况


    一、用内联函数取代宏代码

    • C++语言支持函数内联,其目的是为了提高函数的执行效率(速度)

            在C程序中,可以用宏代码提高执行效率。宏本身不是函数,但使用起来像函数。预处理器用复制宏代码的方式替换函数调用,省去了参数压栈、生成汇编语言的CALL调用、返回参数、执行return等过程,从而提高了速度。使用宏代码最大的缺点是容易出错,预处理器在复制代码时常常产生意想不到的边际效用,如:

    1. #define MAX(a,b) (a)>(b)?(a):(b)
    2. int fun()
    3. {
    4. result=MAX(i,j)+2;
    5. }

            预处理器在处理result时, result=(i)>(j)?(i):(j)+2; 由于运算符' + '的优先级比‘ j ’优先级高,所以该语句的执行为:result=((i)>(j)?(i):(j))+2; 这并不是我们期待的结果。对宏定义添加括号,改为如下所示的代码可以处理该问题

    #define MAX(a,b) ((a)>(b)?(a):(b))

    这是一个问题,对于C++而言,使用宏定义还有一个缺点就是:无法操作类的私有数据成员

    因此引入“内联函数”,在C++程序中,应该用内联函数取代所有宏代码,而且内联函数可以对类型安全检查或者自动类型转换

    二、内联函数和宏定义的区别

    • 内联函数是函数,宏是预处理命令
    • 内联是运行时执行,宏是编译之前执行
    • 内敛不会出现歧义,宏会出现歧义
    •  二义性:
    •         例如 #define S(a,b)  a+b
    •         在main函数内计算 S(3,4)/S(3,4)=3+4/3+4,而不是1
    •         写的时候写到不能加括号为止,用的时候原模原样替换

    三、内联函数的编程风格

    关键字inline必须与函数定义体放在一起才能使函数称为内联,仅将Inline放在函数声明前面不起任何作用。如下所示:

    1. //错误:
    2. inline void Foo(int x,int y);//inline仅仅和函数声明放在一起
    3. void Foo(int x,int y)
    4. {
    5. ...
    6. }
    7. //正确:
    8. void Foo(int x,int y);
    9. inline void Foo(int x,int y)//inline与函数定义体放在一起
    10. {
    11. ...
    12. }

    所以说,inline时一种“用于实现的关键字”,而不是一种“用于声名的关键字”。

    定义在类声明的成员函数将自动地成为内联函数。例如:

    1. class A
    2. {
    3. public:
    4. void Foo(int x,int y){...}//自动成为内联函数
    5. };

    但是将成员函数的定义体放在类声明中虽然能带来书写上的方便,但不是一种良好的编程风格,上例应该写为:

    1. //头文件
    2. class A
    3. {
    4. public:
    5. void Foo(int x,int y);
    6. };
    7. //定义文件
    8. inline void A::Foo(int x,int y)
    9. {
    10. ...
    11. }
    • 函数调用会有空间上和时间上的消耗
    • 有一些函数只做简单功能(赋值、返回、输出...),就可以直接把函数的函数体放在类内
    • 把代码比较短小,功能比较简单的一些函数,放在类里面直接定义,函数调用时直接将函数体嵌入到当前调用处,直接执行,不会有函数调用的转移。

    四、内联函数的分类

    1. 显示内联
    2. 隐式内联
    • 类内定义的内联函数叫做隐式内联 //功能简短编译器会当作内联函数,有些即便在函数名处写了inline但编译器发现函数体比较复杂时,也不会当作内联函数进行编译。函数体名前加入inline是程序员对其的建议。
    • 例如在执行简单的printf函数时,实现是将代码嵌入到主函数内,而复杂函数是执行跑到函数内部,增加了函数时间上的消耗,但是节省了空间的消耗,内嵌函数则相反。
    • 显示内联:函数名前写inline且函数体比较短小,编辑器会按照inline进行编译。

    五、不适用使用内联的情况

    内联函数提高执行效率是以代码膨胀(复制)为代价的。主函数在调用时候,是将内联函数的代码直接放在了主函数的位置上,所以没有指令跳转。指令按顺序执行如果执行函数体内代码的时间,相比于函数调用的开销大,那么效率收获会很少。

    1. 函数体内代码比较长,使用内联函数将导致内存消耗代价较高
    2. 函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大
  • 相关阅读:
    高防ip能不能扛住ddos和CC攻击
    1286_FreeRTOS的任务优先级设置实现分析
    ARM架构指令集--专用指令
    随机规划——报童模型
    4、Java——循环案例代码详解(1)
    Michael Abrash‘s Graphics Programming Black Book--chapter1
    阿里云SLB之:基于多域名调度的SLB七层负载均衡配置(十四)
    线性代数学习笔记11-2:总复习Part2(相似对角化、对称矩阵、奇异值分解SVD)
    金融数字化转型这场硬仗,如何才能做到“有底”和“有数”?
    Java框架 Spring5--IOC
  • 原文地址:https://blog.csdn.net/qq_53830608/article/details/127036305