内联函数和宏

当我们写了一个小函数,函数体只有一两行代码,但是该函数被频繁调用,函数调用有一定的开销,要保存上下文,维护函数栈帧,进行参数拷贝,执行结束还要跳转回去,恢复原现场继续执行等进行一系列工作。为了节省开销,我们首先想到的是使用宏函数来代替,这样确实可以,但是注意宏有很多缺点。

宏的概念:
宏定义将一个标识符定义成一个字符串,源程序中的标识符都以字符串进行替换

宏的优缺点??
优点:

  • 提高程序的可读性,方便修改
  • 提高运行效率,带参数的宏定义可实现函数功能,避免了函数调用时的各种开销,效率提高。
  • 宏在预处理期间进行替换,由预处理器完成一些字符串连接等(#、##)

缺点:

  • 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。
  • 宏是没法调试的。
  • 宏由于类型无关,缺乏类型检测,也就不够严谨。
  • 宏可能会带来运算符优先级的问题,导致程序容易出现错误。

宏与函数相比较

  • 函数调用是在运行时处理,分配临时的内存单元
    内联函数和宏

总的来说,宏只是在预处理期间简单的文本替换,并不进行类型检测,这样预处理语句就不能享受C++严格的类型检查的好处,从而可能成为引发一系列错误的隐患。

内联函数

在函数名前加上inline关键字,该函数就叫做内联函数。它的作用和宏类似,都是对函数进行展开,不用进行函数调用,无压栈等开销。

和宏函数的区别也有不少:

  • 宏函数是在预处理期间预处理器对宏进行替换,而内联函数是编译期间由编译器进行函数展开
  • 内联函数是真正的函数,而宏不是
  • 内联函数参数类似于函数传参,会进行类型检测,宏没有类型的概念
  • 内联函数可调试,宏不可以
  • 宏不能访问对象的私有成员,内联的成员函数有此功能
  • 带参的宏因为只是简单的字符替换,因此时常会产生二义性,而内联函数在调用时会先求表达式的值,然后带入形参。

对于内联函数还有以下几点要特别注意:

  • 用inline修饰函数只是建议编译器内联,编译器会自动优化,若函数体的代码量很大,或是有循环或者递归,编译器此时就不会内联。
  • 对于定义在类内的成员函数默认定义为内联函数。
  • 内联函数必须和函数体申明在一起才有效。只在函数声明前加inline无效。

    C++强烈建议使用内联函数来代替宏函数,使用const变量来代替宏常量,因为他们都在编译期间进行替换,也都会进行类型检测,可大大提高程序的安全性。