举个例子:
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 #define GETMAX(a, b) ((a) > (b) ? (a) : (b)) 6 7 int getMax(int a, int b) { return a > b ? a : b; } 8 int main(int argc, char const* argv[]) { 9 int n1 = getMax(1, 3); 10 int n2 = getMax(2, 4); 11 int n3 = getMax(3, 5); 12 return 0; 13 }
在主函数中多次调用getMax,每次调用时进入getMax在返回主函数,由于getMax本身的功能比较简单,造成多次调用的开销比本身函数的计算开销还要大。
解决方法:
1)使用宏函数
int n1 = GETMAX(1, 3); int n2 = GETMAX(2, 4);
2)使用内联函数
在头文件里面定义内联函数
inline int getMax(int a, int b) { return a > b ? a : b; }
使用宏和内联函数都可以节省在函数调用方面所带来的时间和空间开销。二者都采用了空间换时间的方式,在其调用处进行展开:
(1) 在预编译时期,宏定义在调用处执行字符串的原样替换。在编译时期,内联函数在调用处展开,同时进行参数类型检查。
(2) 内联函数首先是函数,可以像调用普通函数一样调用内联函数。而宏定义往往需要添加很多括号防止歧义,编写更加复杂。
(3) 内联函数可以作为某个类的成员函数,这样可以使用类的保护成员和私有成员。而当一个表达式涉及到类保护成员或私有成员时,宏就不能实现了(无法将this指针放在合适位置)。
可以用内联函数完全替代宏。
在编写内联函数时,函数体应该短小而简洁,不应该包含循环等较复杂结构,否则编译器不会将其当作内联函数看待,而是把它决议成为一个静态函数。
有些编译器甚至会优化内联函数,通常为避免一些不必要拷贝和构造,提高工作效率。
频繁的调用内联函数和宏定义容易造成代码膨胀,消耗更大的内存而造成过多的换页操作。