欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來到入門教程網(wǎng)!

C語言

當(dāng)前位置:主頁 > 軟件編程 > C語言 >

C++ 關(guān)鍵字 inline詳細(xì)介紹

來源:本站原創(chuàng)|時間:2020-01-10|欄目:C語言|點擊: 次

1.  內(nèi)聯(lián)函數(shù)

在C++中我們通常定義以下函數(shù)來求兩個整數(shù)的最大值:

復(fù)制代碼 代碼如下:

int max(int a, int b)
{
 return a > b ? a : b;
}

為這么一個小的操作定義一個函數(shù)的好處有:

① 閱讀和理解函數(shù) max 的調(diào)用,要比讀一條等價的條件表達(dá)式并解釋它的含義要容易得多

② 如果需要做任何修改,修改函數(shù)要比找出并修改每一處等價表達(dá)式容易得多

③ 使用函數(shù)可以確保統(tǒng)一的行為,每個測試都保證以相同的方式實現(xiàn)

④ 函數(shù)可以重用,不必為其他應(yīng)用程序重寫代碼

雖然有這么多好處,但是寫成函數(shù)有一個潛在的缺點:調(diào)用函數(shù)比求解等價表達(dá)式要慢得多。在大多數(shù)的機(jī)器上,調(diào)用函數(shù)都要做很多工作:調(diào)用前要先保存寄存器,并在返回時恢復(fù),復(fù)制實參,程序還必須轉(zhuǎn)向一個新位置執(zhí)行

C++中支持內(nèi)聯(lián)函數(shù),其目的是為了提高函數(shù)的執(zhí)行效率,用關(guān)鍵字 inline 放在函數(shù)定義(注意是定義而非聲明,下文繼續(xù)講到)的前面即可將函數(shù)指定為內(nèi)聯(lián)函數(shù),內(nèi)聯(lián)函數(shù)通常就是將它在程序中的每個調(diào)用點上“內(nèi)聯(lián)地”展開,假設(shè)我們將 max 定義為內(nèi)聯(lián)函數(shù):

復(fù)制代碼 代碼如下:

inline int max(int a, int b)
{
 return a > b ? a : b;
}

則調(diào)用: cout<<max(a, b)<<endl;


在編譯時展開為: cout<<(a > b ? a : b)<<endl;

從而消除了把 max寫成函數(shù)的額外執(zhí)行開銷

2.  內(nèi)聯(lián)函數(shù)和宏

無論是《Effective C++》中的 “Prefer consts,enums,and inlines to #defines” 條款,還是《高質(zhì)量程序設(shè)計指南——C++/C語言》中的“用函數(shù)內(nèi)聯(lián)取代宏”,宏在C++中基本是被廢了,在書《高質(zhì)量程序設(shè)計指南——C++/C語言》中這樣解釋到:

3.  將內(nèi)聯(lián)函數(shù)放入頭文件

關(guān)鍵字 inline 必須與函數(shù)定義體放在一起才能使函數(shù)成為內(nèi)聯(lián),僅將 inline 放在函數(shù)聲明前面不起任何作用。

如下風(fēng)格的函數(shù) Foo 不能成為內(nèi)聯(lián)函數(shù):

復(fù)制代碼 代碼如下:

inline void Foo(int x, int y);   // inline 僅與函數(shù)聲明放在一起  
void Foo(int x, int y)
{
 ...
}

而如下風(fēng)格的函數(shù) Foo 則成為內(nèi)聯(lián)函數(shù):

復(fù)制代碼 代碼如下:

void Foo(int x, int y);  
inline void Foo(int x, int y)   // inline 與函數(shù)定義體放在一起
{
 ...
}

所以說,C++ inline函數(shù)是一種“用于實現(xiàn)的關(guān)鍵字”,而不是一種“用于聲明的關(guān)鍵字”。一般地,用戶可以閱讀函數(shù)的聲明,但是看不到函數(shù)的定義。盡管在大多數(shù)教科書中內(nèi)聯(lián)函數(shù)的聲明、定義體前面都加了 inline 關(guān)鍵字,但我認(rèn)為 inline 不應(yīng)該出現(xiàn)在函數(shù)的聲明中。這個細(xì)節(jié)雖然不會影響函數(shù)的功能,但是體現(xiàn)了高質(zhì)量C++/C 程序設(shè)計風(fēng)格的一個基本原則:聲明與定義不可混為一談,用戶沒有必要、也不應(yīng)該知道函數(shù)是否需要內(nèi)聯(lián)。

定義在類聲明之中的成員函數(shù)將自動地成為內(nèi)聯(lián)函數(shù),例如:

復(fù)制代碼 代碼如下:

class A

public:
 void Foo(int x, int y) { ... }   // 自動地成為內(nèi)聯(lián)函數(shù) 
}

但是編譯器是否將它真正內(nèi)聯(lián)則要看 Foo函數(shù)如何定義

內(nèi)聯(lián)函數(shù)應(yīng)該在頭文件中定義,這一點不同于其他函數(shù)。編譯器在調(diào)用點內(nèi)聯(lián)展開函數(shù)的代碼時,必須能夠找到 inline 函數(shù)的定義才能將調(diào)用函數(shù)替換為函數(shù)代碼,而對于在頭文件中僅有函數(shù)聲明是不夠的。

當(dāng)然內(nèi)聯(lián)函數(shù)定義也可以放在源文件中,但此時只有定義的那個源文件可以用它,而且必須為每個源文件拷貝一份定義(即每個源文件里的定義必須是完全相同的),當(dāng)然即使是放在頭文件中,也是對每個定義做一份拷貝,只不過是編譯器替你完成這種拷貝罷了。但相比于放在源文件中,放在頭文件中既能夠確保調(diào)用函數(shù)是定義是相同的,又能夠保證在調(diào)用點能夠找到函數(shù)定義從而完成內(nèi)聯(lián)(替換)。

但是你會很奇怪,重復(fù)定義那么多次,不會產(chǎn)生鏈接錯誤?

我們來看一個例子:

A.h :

復(fù)制代碼 代碼如下:

class A
{
public:
 A(int a, int b) : a(a),b(b){}
 int max();

private:
 int a;
 int b;
};

A.cpp :

復(fù)制代碼 代碼如下:

#include "A.h"

inline int A::max()
{
 return a > b ? a : b;
}

Main.cpp :

復(fù)制代碼 代碼如下:

#include <iostream>
#include "A.h"
using namespace std;

inline int A::max()
{
 return a > b ? a : b;
}

int main()
{
 A a(3, 5);
 cout<<a.max()<<endl;
 return 0;
}

一切正常編譯,輸出結(jié)果:5

 


倘若你在Main.cpp中沒有定義max內(nèi)聯(lián)函數(shù),那么會出現(xiàn)鏈接錯誤:

error LNK2001: unresolved external symbol "public: int __thiscall A::max(void)" (?max@A@@QAEHXZ)main.obj
找不到函數(shù)的定義,所以內(nèi)聯(lián)函數(shù)可以在程序中定義不止一次,只要 inline 函數(shù)的定義在某個源文件中只出現(xiàn)一次,而且在所有源文件中,其定義必須是完全相同的就可以。

在頭文件中加入或修改 inline 函數(shù)時,使用了該頭文件的所有源文件都必須重新編譯。

4.  慎用內(nèi)聯(lián)

內(nèi)聯(lián)雖有它的好處,但是也要慎用,以下摘自《高質(zhì)量程序設(shè)計指南——C++/C語言》:

而在Google C++編碼規(guī)范中則規(guī)定得更加明確和詳細(xì):

內(nèi)聯(lián)函數(shù):

Tip: 只有當(dāng)函數(shù)只有 10 行甚至更少時才將其定義為內(nèi)聯(lián)函數(shù).

定義: 當(dāng)函數(shù)被聲明為內(nèi)聯(lián)函數(shù)之后, 編譯器會將其內(nèi)聯(lián)展開, 而不是按通常的函數(shù)調(diào)用機(jī)制進(jìn)行調(diào)用.
優(yōu)點: 當(dāng)函數(shù)體比較小的時候, 內(nèi)聯(lián)該函數(shù)可以令目標(biāo)代碼更加高效. 對于存取函數(shù)以及其它函數(shù)體比較短, 性能關(guān)鍵的函數(shù), 鼓勵使用內(nèi)聯(lián).
缺點: 濫用內(nèi)聯(lián)將導(dǎo)致程序變慢. 內(nèi)聯(lián)可能使目標(biāo)代碼量或增或減, 這取決于內(nèi)聯(lián)函數(shù)的大小. 內(nèi)聯(lián)非常短小的存取函數(shù)通常會減少代碼大小, 但內(nèi)聯(lián)一個相當(dāng)大的函數(shù)將戲劇性的增加代碼大小. 現(xiàn)代處理器由于更好的利用了指令緩存, 小巧的代碼往往執(zhí)行更快。
結(jié)論: 一個較為合理的經(jīng)驗準(zhǔn)則是, 不要內(nèi)聯(lián)超過 10 行的函數(shù). 謹(jǐn)慎對待析構(gòu)函數(shù), 析構(gòu)函數(shù)往往比其表面看起來要更長, 因為有隱含的成員和基類析構(gòu)函數(shù)被調(diào)用!
另一個實用的經(jīng)驗準(zhǔn)則: 內(nèi)聯(lián)那些包含循環(huán)或 switch 語句的函數(shù)常常是得不償失 (除非在大多數(shù)情況下, 這些循環(huán)或 switch 語句從不被執(zhí)行).
有些函數(shù)即使聲明為內(nèi)聯(lián)的也不一定會被編譯器內(nèi)聯(lián), 這點很重要; 比如虛函數(shù)和遞歸函數(shù)就不會被正常內(nèi)聯(lián). 通常, 遞歸函數(shù)不應(yīng)該聲明成內(nèi)聯(lián)函數(shù).(遞歸調(diào)用堆棧的展開并不像循環(huán)那么簡單, 比如遞歸層數(shù)在編譯時可能是未知的, 大多數(shù)編譯器都不支持內(nèi)聯(lián)遞歸函數(shù)). 虛函數(shù)內(nèi)聯(lián)的主要原因則是想把它的函數(shù)體放在類定義內(nèi), 為了圖個方便, 抑或是當(dāng)作文檔描述其行為, 比如精短的存取函數(shù).

-inl.h文件:


Tip: 復(fù)雜的內(nèi)聯(lián)函數(shù)的定義, 應(yīng)放在后綴名為 -inl.h 的頭文件中.


內(nèi)聯(lián)函數(shù)的定義必須放在頭文件中, 編譯器才能在調(diào)用點內(nèi)聯(lián)展開定義. 然而, 實現(xiàn)代碼理論上應(yīng)該放在 .cc 文件中, 我們不希望 .h 文件中有太多實現(xiàn)代碼, 除非在可讀性和性能上有明顯優(yōu)勢.

如果內(nèi)聯(lián)函數(shù)的定義比較短小, 邏輯比較簡單, 實現(xiàn)代碼放在 .h 文件里沒有任何問題. 比如, 存取函數(shù)的實現(xiàn)理所當(dāng)然都應(yīng)該放在類定義內(nèi). 出于編寫者和調(diào)用者的方便, 較復(fù)雜的內(nèi)聯(lián)函數(shù)也可以放到 .h 文件中, 如果你覺得這樣會使頭文件顯得笨重, 也可以把它萃取到單獨的 -inl.h 中. 這樣把實現(xiàn)和類定義分離開來, 當(dāng)需要時包含對應(yīng)的 -inl.h 即可。

本文參考書目:《C++ Primer》、《高質(zhì)量程序設(shè)計指南——C++/C語言》、Google C++編碼規(guī)范

上一篇:一個快速排序算法代碼分享

欄    目:C語言

下一篇:純c語言實現(xiàn)面向?qū)ο蠓治雠c示例分享

本文標(biāo)題:C++ 關(guān)鍵字 inline詳細(xì)介紹

本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3812.html

網(wǎng)頁制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語言數(shù)據(jù)庫服務(wù)器

如果侵犯了您的權(quán)利,請與我們聯(lián)系,我們將在24小時內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有