• 产生背景
      替代 C 中复杂易错不易维护的宏函数
    • 编译器处理
      编译阶段
      函数调用——替换——函数本体
      建议:编译器可能做也可能不做
    • 优势
      可消除所有与调用相关的痕迹以及性能的损失
    • 缺点
      1、代码膨胀(以空间换时间),消耗更多的内存空间
      2、无法随着函数库升级而升级(需要重新编译,若是non-inline则可动态链接,重新链接即可)
      3、是否内联,程序员不可控(仅对编译器建议而非强制,出现递归可能不支持inline)
    • 使用
      在返回类型前添加inline,即在行首添加
      定义时必须添加
      申明时添加可选,但推荐添加(代码即注释)
      注意:只申明添加定义不加时不是内联,即inline只在函数定义起作用,申明时类似注释
      • 注意事项
        • 使用函数指针调用内联函数将会导致内联失败
        • 如果函数体代码过长或者有多重循环语句,if或witch分支语句或递归时,不宜用内联
        • 类的 constructors、destructors 和虚函数往往不是 inline 函数的最佳选择
          构造、析构会调用其父类,隐藏着大量代码——不适于inline
          虚函数是运行时确定,inline是编译时——内联无效
        • 在多个源文件中被用到,那么必须把它定义在头文件中
          内联展开是在编译时进行的,只有链接的时候源文件之间才有关系
          链接器在链接的过程中,会删除多余的inline函数实体,只保留一份,所以不会报重定义错误,因此我们不需要使用 static 关键字去多余地修饰inline函数
        • 推荐static inline func
          static 实际不是来修饰内联函数的,而是在编译器未对func内联时确保其static
    • VS宏函数
      • 相同
        调用处进行代码展开,省去了参数压栈、栈帧开辟与回收,结果返回等,从而提高程序运行速度
      • 不同
        1、在代码展开时,会做安全检查或自动类型转换(同普通函数),而宏定义则不会
        2、在类中声明同时定义的成员函数,自动转化为内联函数,因此内联函数可以访问类的成员变量,宏定义则不能 #疑问❓
        3、内联函数在运行时可调试,而宏定义不可以