内联函数与宏区别
需要在函数前加上关键字inline
,但inline
是建议性关键字,当请求将函数作为内联函数时,编译器并不一定会满足这种要求。内联函数尽量避免函数体过长、含有循环、递归。
内联函数的优势在于做参数类型检查,而宏定义不会,宏只是简单的文本替换。
1、宏不能访问对象的私有成员。
2、宏的定义很容易产生二意性。
内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。
我们可以用Inline来定义内联函数,不过,任何在类的说明部分定义的函数都会被自动的认为是内联函数。
当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。这样,内联函数就和普通函数执行效率一样了。
对于C++中内联机制的一个常见误解是:关键字"inline"只是对编译器的建议,如果编译器发现指定的函数不适合内联就不会内联;所以即使内联使用的不恰当也不会有任何副作用。这句话只对了一半,内联使用不恰当是会有副作用的:会带来代码膨胀,还有可能引入难以发现的程序臭虫。
根据规范,当编译器认为希望被内联的函数不适合内联的时候,编译器可以不内联该函数。但是不内联该函数不代表该函数就是一个普通函数了,从编译器的实际实现上来讲,内联失败的函数与普通函数是有区别的:
(1)普通的函数在编译时被单独编译一个对象,包含在相应的目标文件中。目标文件链接时,函数调用被链接到该对象上。
(2)若一个函数被声明成内联函数,编译器即使遇到该函数的声明也不会为该函数编译出一个对象,因为内联函数是在用到的地方展开的。可是若在调用该内联函数的地方发现该内联函数的不适合展开时怎么办?一种选择是在调用该内联函数的目标文件中为该内联函数编译一个对象。这么做的直接后果是:若在多个文件调用了内联失败的函数,其中每个文件对应的目标文件中都会包含一份该内联函数的目标代码。
#define SQUARE(X) X*X
a = SQUARE(5.0); // a = 5.0 * 5.0
b = SQUARE(4.3 + 3.1); // 4.3 + 3.1 * 4.3 + 3.1
c = SQUARE(d++) // c == d++ * d++ d递增两次
宏定义时不能忘记括号的使用,否则会造成运算错误。但是上述代码中,加上括号仍然会出现错误,在第三个函数中,d依旧递增两次。如果使用内联函数,则是计算出 d 的值在进行传递,并进行运算,就只会递增一次。
原文地址:https://www.cnblogs.com/xlsss159/p/10361172.html