文章目录
前言
c++与c的一个区别就是针对宏的缺陷增加了内联函数这一概念,那么宏究竟有什么缺陷,内联函数又怎样去使用呢,让我们一起去看看吧。
一、内联函数的引出
c++从c中继承的一个重要特征就是效率。假如c++的效率明显低于c的效率,那么就会有很大的一批程序员不去使用c++了。
在c中我们经常把一些短并且执行频繁的计算写成宏,而不是函数,这样做的理由是为了执行效率,宏可以避免函数调用的开销,这些都由预处理来完成。
但是在c++出现之后,使用预处理宏会出现两个问题:
- 第一个在c中也会出现,宏看起来像一个函数调用,但是会有隐藏一些难以发现的错误。
- 第二个问题是c++特有的,预处理器不允许访问类的成员,也就是说预处理器宏不能用作类类的成员函数。
为了保持预处理宏的效率又增加安全性,而且还能像一般成员函数那样可以在类里访问自如,c++引入了内联函数。
内联函数为了继承宏函数的效率,没有函数调用时开销,然后又可以像普通函数那样,可以进行参数,返回值类型的安全检查,又可以作为成员函数。
二、预处理宏的缺陷
1.计算顺序会被改变
代码如下(示例):
#define ADD(x,y) x+y
inline int Add(int x,int y){
return x + y;
}
void test(){
int ret1 = ADD(10, 20) * 10; //希望的结果是300
int ret2 = Add(10, 20) * 10; //希望结果也是300
cout << "ret1:" << ret1 << endl; //210
cout << "ret2:" << ret2 << endl; //300
}
可以看到,编译器在执行宏的时候是直接进行替换,替换后的结果为ret1=10+20*10,造成了计算顺序的改变,导致结果错误,为了避免该错误,我们往往要使用括号,#define ADD(x,y) ((x)+(y)),将宏定义进行这样的修改,可避免该错误,但依旧有些问题无法解决,我们来看问题二。
2.传参时容易出现问题
#define COMPARE(x,y) ((x) < (y) ? (x) : (y))
int Compare(int x,int y){
return x < y ? x : y;
}
void test02(){
int a = 1;
int b = 3;
//cout << "COMPARE(++a, b):" << COMPARE(++a, b) << endl; // 3
cout << "Compare(int x,int y):" << Compare(++a, b) << endl; //2
}
我们以一个简单的比较函数为例,用宏进行替换的时候,会将++a直接替换进去,替换结果如下,((++a)<(b)?(++a):(b)),这样会导致++a会执行两次,和我们的本意不符。
3.宏没有作用域的概念
预定义宏函数没有作用域概念,无法作为一个类的成员函数,也就是说预定义宏没有办法表示类的范围。
4.无法进行调试
在调试过程中无法进入到宏的内部。
三、内联函数
1.内敛函数的基本概念
内敛函数本身也是一个函数,他具有普通函数的所有行为,唯一的区别是,内敛函数会像预定义宏一样展开,免去了函数调用的开销。
在普通函数(非成员函数)函数前面加上inline关键字使之成为内联函数。但是必须注意必须函数体和声明结合在一起,否则编译器将它作为普通函数来对待。
inline void func(int a); //以上写法没有任何效果,仅仅是声明函数。
内联函数的确会占用空间,但它比普通函数省去了调用的时间,我们可以理解为内联函数是一种以空间换时间的行为。
2.类内部的内敛函数
为了定义内联函数,通常必须在函数定义前面放一个inline关键字。但是在类内部定义内联函数时并不是必须的。任何在类内部定义的函数自动成为内联函数。
class Person{
public:
Person(){ cout << "构造函数!" << endl; }
void PrintPerson(){ cout << "输出Person!" << endl; }
}
构造函数Person,成员函数PrintPerson在类的内部定义,自动成为内联函数。
3.内联函数与编译器
内联函数不是何时何地都会有效,c++编译器会对内联函数进行一定的限制,在以下情况时,编译器可能会考虑不适用内敛函数。
- 不能存在任何形式的循环语句
- 不能存在过多的条件判断语句
- 函数体过于庞大
- 不能对函数进行取址操作
内联仅仅是一个建议,编译器不一定采用。而一个好的编译器,有时也会自己对函数进行内联。我们好比是一个军师,只能提意见,最终决定权还在编译器这个司令官手里。
总结
例如:以上就是今天要讲的内容,本文仅仅简单介绍了宏的缺陷已经内联函数,希望能给大家带来帮助。