最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2014年01月26日 16:16:24   投稿:shangke  
這篇文章主要介紹了C++ 關(guān)鍵字 inline,有需要的朋友可以參考一下

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

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

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

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

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

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

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

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

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

雖然有這么多好處,但是寫成函數(shù)有一個(gè)潛在的缺點(diǎn):調(diào)用函數(shù)比求解等價(jià)表達(dá)式要慢得多。在大多數(shù)的機(jī)器上,調(diào)用函數(shù)都要做很多工作:調(diào)用前要先保存寄存器,并在返回時(shí)恢復(fù),復(fù)制實(shí)參,程序還必須轉(zhuǎn)向一個(gè)新位置執(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ù)通常就是將它在程序中的每個(gè)調(diào)用點(diǎn)上“內(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;


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

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

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

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

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ù)定義體放在一起
{
 ...
}

所以說(shuō),C++ inline函數(shù)是一種“用于實(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ù)的聲明中。這個(gè)細(xì)節(jié)雖然不會(huì)影響函數(shù)的功能,但是體現(xiàn)了高質(zhì)量C++/C 程序設(shè)計(jì)風(fēng)格的一個(gè)基本原則:聲明與定義不可混為一談,用戶沒(méi)有必要、也不應(yīng)該知道函數(shù)是否需要內(nèi)聯(lián)。

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

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

class A

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

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

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

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

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

我們來(lái)看一個(gè)例子:

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中沒(méi)有定義max內(nèi)聯(lián)函數(shù),那么會(huì)出現(xiàn)鏈接錯(cuò)誤:

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

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

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

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

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

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

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

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

-inl.h文件:


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


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

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

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

相關(guān)文章

  • C語(yǔ)言之陷阱與缺陷詳解

    C語(yǔ)言之陷阱與缺陷詳解

    本片文章是對(duì)C++中陷阱與缺陷進(jìn)行了詳細(xì)的分析介紹,小編覺(jué)得本片文章講解的非常詳細(xì),需要的朋友參考下,希望能夠給你帶來(lái)幫助
    2021-09-09
  • C++?LeetCode1827題解最少操作使數(shù)組遞增

    C++?LeetCode1827題解最少操作使數(shù)組遞增

    這篇文章主要為大家介紹了C++?LeetCode1827題解最少操作使數(shù)組遞增示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • C++ RTTI與4種類型轉(zhuǎn)換的深入理解

    C++ RTTI與4種類型轉(zhuǎn)換的深入理解

    這篇文章主要給大家介紹了關(guān)于C++ RTTI與4種類型轉(zhuǎn)換的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • VS2019開發(fā)Linux C++程序的實(shí)現(xiàn)步驟

    VS2019開發(fā)Linux C++程序的實(shí)現(xiàn)步驟

    由于很多unix特有的函數(shù)無(wú)法在Windows上使用,而Vim又用的不太順手,突然想到最初用vs的時(shí)候有一個(gè)基于Linux的C++開發(fā)。本文就來(lái)介紹一下,感興趣的可以了解一下
    2021-07-07
  • C語(yǔ)言野指針及如何規(guī)避詳解

    C語(yǔ)言野指針及如何規(guī)避詳解

    這篇文章主要為大家介紹了C語(yǔ)言野指針及如何規(guī)避詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • C++中stack容器的使用

    C++中stack容器的使用

    本文主要介紹了C++中stack容器的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • C語(yǔ)言實(shí)現(xiàn)二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的示例詳解

    C語(yǔ)言實(shí)現(xiàn)二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的示例詳解

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定的幫助,需要的可以參考一下
    2022-11-11
  • 淺析C++中前置聲明的應(yīng)用與陷阱

    淺析C++中前置聲明的應(yīng)用與陷阱

    以下是對(duì)C++中前置聲明的應(yīng)用與陷阱進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • C語(yǔ)言小項(xiàng)目計(jì)時(shí)器的實(shí)現(xiàn)思路(倒計(jì)時(shí)+報(bào)警提示)

    C語(yǔ)言小項(xiàng)目計(jì)時(shí)器的實(shí)現(xiàn)思路(倒計(jì)時(shí)+報(bào)警提示)

    這篇文章主要介紹了C語(yǔ)言小項(xiàng)目計(jì)時(shí)器(倒計(jì)時(shí)+報(bào)警提示)的實(shí)現(xiàn)思路,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • c語(yǔ)言動(dòng)態(tài)內(nèi)存分配知識(shí)點(diǎn)及實(shí)例

    c語(yǔ)言動(dòng)態(tài)內(nèi)存分配知識(shí)點(diǎn)及實(shí)例

    在本篇文章里小編給大家整理的是關(guān)于c語(yǔ)言動(dòng)態(tài)內(nèi)存分配知識(shí)點(diǎn)及實(shí)例,需要的朋友們可以學(xué)習(xí)下。
    2020-03-03

最新評(píng)論

革吉县| 民乐县| 昌吉市| 普兰店市| 江华| 金川县| 天柱县| 类乌齐县| 甘孜| 布尔津县| 肥乡县| 姜堰市| 芦溪县| 宜春市| 武义县| 平山县| 定结县| 阜新| 开阳县| 威远县| 黄石市| 麻江县| 凤凰县| 阿图什市| 岳阳县| 乾安县| 边坝县| 梅州市| 乌鲁木齐市| 盐山县| 郁南县| 墨玉县| 珲春市| 安乡县| 聂拉木县| 锦州市| 襄城县| 江孜县| 青龙| 阜新市| 光泽县|