C++:inline与#define的区别

内联函数inline

  • 概念:

        以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销, 从而能够提升程序运行的效率。

  • 特性:
  1. inline是一种以空间换时间的做法,省去调用函数的开销。所以代码很长或者有循环/递归的函数不适宜作为内联函数。
  2. inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等 ,编译器优化时会忽略掉内联。
  3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
  4. 内联函数不能是虚函数。(原因:inline是通过编译器将函数内容替换到函数调用处,是静态编译的。而虚函数是动态调用的,在编译器并不知道需要调用的是父类还是子类的虚函数,所以不能够inline声明展开,因此编译器会忽略
  • 使用:
  1. 在C++中,在类的内部定义了函数体的成员函数默认是内联函数,不管是否有inline关键字。 
  2. 在内联函数内不允许用循环语句、开关语句和递归调用等,且函数体不宜过长,否则作为普通函数处理。
  3. 内联函数的定义必须出现在第一次被调用之前。如果在前面声明为普通函数,而在调用代码后面才定义为一个inline函数,程序可以通过编译,但该函数没有实现inline。
  4. 如果一个inline函数会在多个源文件中被用到,那么必须把它定义在头文件中。解析:如果内联函数fun()定义在某个编译单元A中,那么其他编译单元中调用fun()的地方时,可以编译通过(此时并没有展开,结合第三条,此时虽然头文件声明了该inline函数,但此时调用时,还没定义,所以作为普通函数处理)。当链接时将无法解析该符号,出现链接错误。 因为inline函数是作为内部连接存在的,只能够被本模块访问
  • 特点: 

        inline函数是函数,有类型,要做类型检查,因此安全可靠,可以得到一定效率的提升,这个是以增加空间的消耗为代价


宏替换#define

  • 概念:

        定义预编译时处理的宏,只是简单的字符串替换,无类型检查

  • 特性:
  1. 在宏扩展时,只对宏名做简单的代换,不做任何计算,也不做任何语法检查。
  2. 宏由编译预处理程序处理
  3. 宏定义可出现在程序的任何位置。
  4. 在宏定义中可以使用已定义的宏名。
  • 使用:
  1. 不带参数的宏定义格式:#define 标识符 字符或字符串
  2. 带参数的宏定义格式:   #define 宏名(参数表) 使用参数的字符或字符串
  • 特点:

        define无类型,不做检查就直接替换,因此并不安全,会带有副作用;宏不能调试,会使得代码变得庞大。


区别

  1. 内联函数在编译时展开,宏在预编译时由预处理器进行展开。
  2. 内联函数会检查参数类型,宏定义不检查函数参数 ,所以内联函数更安全。
  3. inline函数是函数,宏不是函数。
  4. 宏在定义时要小心处理宏参数(一般情况是把参数用括弧括起来),否则易出现二义性,而内联定义不会出现。
  5. 编译内联函数可以嵌入到目标代码,宏只是简单文本替换。

 

      基于上述区别中的第2点,为了保证安全性在C++中尽量使用inline代替宏。

 

  1.  

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值