C++中的內(nèi)聯(lián)函數(shù)提供了宏之上的功能。宏是內(nèi)聯(lián)代碼的簡(jiǎn)單實(shí)現(xiàn)形式。。不過(guò)兩者有很大的區(qū)別。
專業(yè)成都網(wǎng)站建設(shè)公司,做排名好的好網(wǎng)站,排在同行前面,為您帶來(lái)客戶和效益!創(chuàng)新互聯(lián)為您提供成都網(wǎng)站建設(shè),五站合一網(wǎng)站設(shè)計(jì)制作,服務(wù)好的網(wǎng)站設(shè)計(jì)公司,成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站負(fù)責(zé)任的成都網(wǎng)站制作公司!
內(nèi)聯(lián)函數(shù)采用的是值傳遞,而宏定義采用的是對(duì)等替換。這一點(diǎn)非常重要,宏定義沒(méi)用好,很可能在使用過(guò)程中陷入誤區(qū)。
例如下面這個(gè)宏:
#define
MAX(a,
b)
ab?a:b
當(dāng)我們這樣使用宏時(shí),沒(méi)有什么問(wèn)題:
MAX(
num1,
num2
);
因?yàn)楹暾归_(kāi)后變成
num1num2?num1:num2;。
但是,如果是這樣調(diào)用的,MAX(
17+32,
25+21);
呢,編譯時(shí)出現(xiàn)錯(cuò)誤,原因是,宏展開(kāi)后變成:17+3225+21?17+32:25+21,Woh,這是什么?。?/p>
所以,宏在使用時(shí),參數(shù)一定要加上括號(hào),上述的那個(gè)例子改成如下所示就能解決問(wèn)題了。
#define
MAX(
(a),
(b)
)
(a)(b)?(a)b)
即使是這樣,也不這個(gè)宏也還是有Bug,因?yàn)槿绻疫@樣調(diào)用
MAX(i++,j++);
,
經(jīng)過(guò)這個(gè)宏以后,i和j都被累加了兩次,這絕不是我們想要的。所以,在宏的使用上還是要謹(jǐn)慎考慮,因?yàn)楹暾归_(kāi)是的結(jié)果是很難讓人預(yù)料的。而且雖然,宏的執(zhí)行很快(因?yàn)闆](méi)有函數(shù)調(diào)用的開(kāi)銷),但宏會(huì)讓源代碼澎漲,使目標(biāo)文件尺寸變大,(如:一個(gè)50行的宏,程序中有1000個(gè)地方用到,宏展開(kāi)后會(huì)很不得了),相反不能讓程序執(zhí)行得更快(因?yàn)閳?zhí)行文件變大,運(yùn)行時(shí)系統(tǒng)換頁(yè)頻繁)。因此,在決定是用函數(shù),還是用宏時(shí)得要小心。
相同點(diǎn):兩者都是在預(yù)處理階段,對(duì)代碼塊,進(jìn)行替換。。
內(nèi)聯(lián)函數(shù)與宏的區(qū)別:
傳統(tǒng)的宏定義函數(shù)可能會(huì)引起一些麻煩。
ex:
#define F(x) x+x
void main(){int i=1;F(i++);}
這里x將被加兩次。
內(nèi)聯(lián)函數(shù)被編譯器自動(dòng)的用函數(shù)的形勢(shì)添加進(jìn)代碼,而不會(huì)出現(xiàn)這種情況。
內(nèi)聯(lián)函數(shù)的使用提高了效率(省去了很多函數(shù)調(diào)用匯編代碼如:call和ret等)。
應(yīng)該是c++中才有的,
inline 關(guān)鍵字用來(lái)定義一個(gè)類的內(nèi)聯(lián)函數(shù),引入它的主要原因是用它替代C中表達(dá)式形式的宏定義。
表達(dá)式形式的宏定義一例:
#define ExpressionName(Var1,Var2) (Var1+Var2)*(Var1-Var2)
為什么要取代這種形式呢,且聽(tīng)我道來(lái):
1.
首先談一下在C中使用這種形式宏定義的原因,C語(yǔ)言是一個(gè)效率很高的語(yǔ)言,這種宏定義在形式及使用上像一個(gè)函數(shù),但它使用預(yù)處理器實(shí)現(xiàn),沒(méi)有了參數(shù)壓棧,代碼生成等一系列的操作,因此,效率很高,這是它在C中被使用的一個(gè)主要原因。
2.
這種宏定義在形式上類似于一個(gè)函數(shù),但在使用它時(shí),僅僅只是做預(yù)處理器符號(hào)表中的簡(jiǎn)單替換,因此它不能進(jìn)行參數(shù)有效性的檢測(cè),也就不能享受C++編譯器嚴(yán)格類型檢查的好處,另外它的返回值也不能被強(qiáng)制轉(zhuǎn)換為可轉(zhuǎn)換的合適的類型,這樣,它的使用就存在著一系列的隱患和局限性。
3.
在C++中引入了類及類的訪問(wèn)控制,這樣,如果一個(gè)操作或者說(shuō)一個(gè)表達(dá)式涉及到類的保護(hù)成員或私有成員,你就不可能使用這種宏定義來(lái)實(shí)現(xiàn)(因?yàn)闊o(wú)法將this指針?lè)旁诤线m的位置)。
4. inline 推出的目的,也正是為了取代這種表達(dá)式形式的宏定義,它消除了它的缺點(diǎn),同時(shí)又很好地繼承了它的優(yōu)點(diǎn)。
為什么inline能很好地取代表達(dá)式形式的預(yù)定義呢?
對(duì)應(yīng)于上面的1-3點(diǎn),闡述如下:
1. inline 定義的類的內(nèi)聯(lián)函數(shù),函數(shù)的代碼被放入符號(hào)表中,在使用時(shí)直接進(jìn)行替換,(像宏一樣展開(kāi)),沒(méi)有了調(diào)用的開(kāi)銷,效率也很高。
2.
很明顯,類的內(nèi)聯(lián)函數(shù)也是一個(gè)真正的函數(shù),編譯器在調(diào)用一個(gè)內(nèi)聯(lián)函數(shù)時(shí),會(huì)首先檢查它的參數(shù)的類型,保證調(diào)用正確。然后進(jìn)行一系列的相關(guān)檢查,就像對(duì)待任何一個(gè)真正的函數(shù)一樣。這樣就消除了它的隱患和局限性。
3. inline 可以作為某個(gè)類的成員函數(shù),當(dāng)然就可以在其中使用所在類的保護(hù)成員及私有成員。
在何時(shí)使用inline函數(shù):
首先,你可以使用inline函數(shù)完全取代表達(dá)式形式的宏定義。
另外要注意,內(nèi)聯(lián)函數(shù)一般只會(huì)用在函數(shù)內(nèi)容非常簡(jiǎn)單的時(shí)候,這是因?yàn)?,?nèi)聯(lián)函數(shù)的代碼會(huì)在任何調(diào)用它的地方展開(kāi),如果函數(shù)太復(fù)雜,代碼膨脹帶來(lái)的惡果很可能會(huì)大于效率的提高帶來(lái)的益處。
提高效率。
這個(gè)是主要意義。
要知道
調(diào)用一個(gè)函數(shù),是需要時(shí)間的
而且 耗費(fèi)不是太小。
在要求效率比較高的情況下,使用宏 或者內(nèi)聯(lián),可以使代碼清爽的同時(shí),不降低效率。
函數(shù)內(nèi)聯(lián)
用內(nèi)聯(lián)取代宏代碼
----------------
C++
語(yǔ)言支持函數(shù)內(nèi)聯(lián),其目的是為了提高函數(shù)的執(zhí)行效率(速度)。
在C程序中,可以用宏代碼提高執(zhí)行效率。宏代碼本身不是函數(shù),但使用起來(lái)象函數(shù)。
預(yù)處理器用復(fù)制宏代碼的方式代替函數(shù)調(diào)用,省去了參數(shù)壓棧、生成匯編語(yǔ)言的CALL調(diào)用、
返回參數(shù)、執(zhí)行return等過(guò)程,從而提高了速度。
使用宏代碼最大的缺點(diǎn)是容易出錯(cuò),預(yù)處理器在復(fù)制宏代碼時(shí)常常產(chǎn)生意想不到的邊際效應(yīng)。
對(duì)于C++
而言,使用宏代碼還有另一種缺點(diǎn):無(wú)法操作類的私有數(shù)據(jù)成員。
讓我們看看C++
的"函數(shù)內(nèi)聯(lián)"是如何工作的。
對(duì)于任何內(nèi)聯(lián)函數(shù),編譯器在符號(hào)表里放入函數(shù)的聲明(包括名字、參數(shù)類型、返回值類型)。
如果編譯器沒(méi)有發(fā)現(xiàn)內(nèi)聯(lián)函數(shù)存在錯(cuò)誤,那么該函數(shù)的代碼也被放入符號(hào)表里。
在調(diào)用一個(gè)內(nèi)聯(lián)函數(shù)時(shí),編譯器首先檢查調(diào)用是否正確
(進(jìn)行類型安全檢查,或者進(jìn)行自動(dòng)類型轉(zhuǎn)換,當(dāng)然對(duì)所有的函數(shù)都一樣)。
如果正確,內(nèi)聯(lián)函數(shù)的代碼就會(huì)直接替換函數(shù)調(diào)用,于是省去了函數(shù)調(diào)用的開(kāi)銷。
這個(gè)過(guò)程與預(yù)處理有顯著的不同,因?yàn)轭A(yù)處理器不能進(jìn)行類型安全檢查,或者進(jìn)行自動(dòng)類型轉(zhuǎn)換。
假如內(nèi)聯(lián)函數(shù)是成員函數(shù),對(duì)象的地址(this)會(huì)被放在合適的地方,這也是預(yù)處理器辦不到的。
C++
語(yǔ)言的函數(shù)內(nèi)聯(lián)機(jī)制既具備宏代碼的效率,又增加了安全性,而且可以自由操作類的數(shù)據(jù)成員。
所以在C++
程序中,應(yīng)該用內(nèi)聯(lián)函數(shù)取代所有宏代碼,"斷言assert"恐怕是唯一的例外。
assert是僅在Debug版本起作用的宏,它用于檢查"不應(yīng)該"發(fā)生的情況。
為了不在程序的Debug版本和Release版本引起差別,assert不應(yīng)該產(chǎn)生任何副作用。
如果assert是函數(shù),由于函數(shù)調(diào)用會(huì)引起內(nèi)存、代碼的變動(dòng),那么將導(dǎo)致Debug版本與Release版本存在差異。
所以assert不是函數(shù),而是宏。