當前位置:首頁 » 編程軟體 » 內聯成員函數編譯

內聯成員函數編譯

發布時間: 2022-09-12 06:46:32

『壹』 內聯函數

    c++從c中繼承的一個重要特徵就是效率。假如c++的效率明顯低於c的效率,那麼就會有很大的一批程序員不去使用c++了。
    在c中我們經常把一些短並且執行頻繁的計算寫成宏,而不是函數,這樣做的理由是為了執行效率,宏可以避免函數調用的開銷,這些都有預處理來完成。
    但是在c++出現之後,使用預處理宏會出現兩個問題:

    為了保持預處理宏的效率又增加安全性,而且還能像一般成員函數那樣可以在類里訪問自如,c++引入了內聯函數(inline function).
    內聯函數為了繼承宏函數的效率,沒有函數調用時開銷,然後又可以像普通函數那樣,可以進行參數,返回值類型的安全檢查,又可以作為成員函數。

    預處理器宏存在問題的關鍵是我們可能認為預處理器的行為和編譯器的行為是一樣的。當然也是由於宏函數調用和函數調用在外表看起來是一樣的,因為也容易被混淆。但是其中也會有一些微妙的問題出現:
問題1

問題2:

問題3:
    預定義宏函數沒有作用域概念,無法作為一個類的成員函數,也就是說預定義宏沒有辦法表示類的范圍。

    在c++中,預定義宏的概念是用內聯函數來實現的,而內聯函數本身也是一個真正的函數。內聯函數具有普通函數的所有行為。唯一不同之處在於內聯函數會在適當的地方像預定義宏一樣展開,所以不需要函數調用的開銷。因此應該不使用宏,使用內聯函數。

    內聯函數的確佔用空間,但是內聯函數相對於普通函數的優勢只是省去了函數調用時候的壓棧,跳轉,返回的開銷。我們可以理解為內聯函數是以 空間換時間

    為了定義內聯函數,通常必須在函數定義前面放一個inline關鍵字。但是在類內部定義內聯函數時並不是必須的。任何在類內部定義的函數自動成為內聯函數。

     構造函數Person,成員函數PrintPerson在類的內部定義,自動成為內聯函數,當然也並不是所有的函數都是內聯函數,因為編譯器會根據函數的復雜度來決定是否要把函數當作內聯函數。

    內聯函數並不是何時何地都有效,為了理解內聯函數何時有效,應該要知道編譯器碰到內聯函數會怎麼處理?
    對於任何類型的函數,編譯器會將函數類型(包括函數名字,參數類型,返回值類型)放入到符號表中。同樣,當編譯器看到內聯函數,並且對內聯函數體進行分析沒有發現錯誤時,也會將內聯函數放入符號表。
    當調用一個內聯函數的時候,編譯器首先確保傳入參數類型是正確匹配的,或者如果類型不正完全匹配,但是可以將其轉換為正確類型,並且返回值在目標表達式里匹配正確類型,或者可以轉換為目標類型,內聯函數就會直接替換函數調用,這就消除了函數調用的開銷。假如內聯函數是成員函數,對象this指針也會被放入合適位置。
    類型檢查和類型轉換、包括在合適位置放入對象this指針這些都是預處理器不能完成的(不能通過宏來實現)。
    但是c++內聯編譯會有一些限制,以下情況編譯器可能考慮不會將函數進行內聯編譯:

    內聯僅僅只是給編譯器一個建議,編譯器不一定會接受這種建議,如果你沒有將函數聲明為內聯函數,那麼編譯器也可能將此函數做內聯編譯。一個好的編譯器將會內聯小的、簡單的函數。

『貳』 C++內聯函數在 在編譯時是將該函數的目標代碼插入每個調用該函數的地方

內聯函數在調用時,是將調用表達式用內聯函數體來替換,而一般函數進行調用時,要將程序執行權轉到被調用函數中,然後再返回到調用它的函數中。

如果內聯失敗這個函數就是一個普通的函數,普通的函數不會被編譯器展開,只是作為函數調用。內聯函數比普通函數效率高的原因就是編譯器在調用處把這個函數展開,展開就是直接執行代碼而不是調用這個函數,像宏展開的意思。

(2)內聯成員函數編譯擴展閱讀:

宏調用並不執行類型檢查,甚至連正常參數也不檢查,但是函數調用卻要檢查。c語言的宏使用的是文本替換,可能導致無法預料的後果,因為需要重新計算參數和操作順序。在宏中的編譯錯誤很難發現,因為它們引用的是擴展的代碼,而不是程序員鍵入的。

許多結構體使用宏或者使用不同的語法來表達很難理解。內聯函數使用與普通函數相同的語言,可以隨意的內聯和不內聯。

『叄』 內聯成員函數的優缺點【C++】

優點是提高運行時間效率,缺點是增加了空間開銷
對於普通函數,函數調用需要時間和空間開銷,調用函數實際上將程序執行流程轉移到被調函數中,被調函數的代碼執行完後,再返回到調用的地方。這種調用操作要求調用前保護好現場並記憶執行的地址,返回後恢復現場,並按原來保存的地址繼續執行。對於較長的函數這種開銷可以忽略不計,但對於一些函數體代碼很短,又被頻繁調用的函數,就不能忽視這種開銷。引入內聯函數正是為了解決這個問題,提高程序的運行效率。
對於內聯函數,在程序編譯時,編譯器將程序中出現的內聯函數的調用表達式用內聯函數的函數體來進行替換。由於在編譯時將內聯函數體中的代碼替代到程序中,因此會增加目標程序代碼量,進而增加空間開銷,而在時間開銷上不象函數調用時那麼大,可見它是以目標代碼的增加為代價來換取時間的節省。

『肆』 用C++編程,關於內聯函數和成員函數的!謝謝啦~

#include<iostream>
usingnamespacestd;
classssmemset{
private:
inta[20];
public: //兩個重載的構造函數,類內默認為內聯函數。
ssmemset()
{
for(inti=0;i<20;i++)
a[i]=0;
}
ssmemset(ints1[])
{
for(inti=0;i<20;i++)
a[i]=s1[i];
}
voidprint();
};

inlinevoidssmemset::print() //外部定義的內聯函數。
{
inti;
for(i=0;i<20;i++)
cout<<a[i]<<' ';
cout<<endl;
};

voidmain()
{
inta[20]={1,3,5,7};
ssmemsetA;
ssmemsetB(a);
A.print();
B.print();
}

memset是標准庫的關鍵字不能用來聲明類名。

『伍』 內聯函數與普通函數比較,在聲明、編譯時有什麼不同

在類聲明的內部聲明或定義的成員函數叫做內聯(INLINE)函數.
引入內聯函數的目的是為了解決程序中函數調用的效率問題。
在程序編譯時,編譯器將程序中出現的內聯函數的調用表達式用內聯函數的函數體來進行替換。顯然,這種做法不會產生轉去轉回的問題,但是由於在編譯時將函數體中的代碼被替代到程序中,因此會增加目標程序代碼量,進而增加空間開銷,而在時間代銷上不象函數調用時那麼大,可見它是以目標代碼的增加為代價來換取時間的節省。
在程序中,調用其函數時,該函數在編譯時被替代,而不是像一般函數那樣是在運行時被調用。

函數調用也會帶來降低效率的問題,因為調用函數實際上將程序執行順序轉移到函數所存放在內存中某個地址,將函數的程序內容執行完後,再返回到轉去執行該函數前的地方。這種轉移操作要求在轉去前要保護現場並記憶執行的地址,轉回後先要恢復現場,並按原來保存地址繼續執行。因此,函數調用要有一定的時間和空間方面的開銷,於是將影響其效率。特別是對於一些函數體代碼不是很大,但又頻繁地被調用的函數來講,解決其效率問題更為重要。引入內聯函數實際上就是為了解決這一問題。

『陸』 C++中內聯函數是什麼意思

內聯函數具有一般函數的特性,它與一般函數所不同之處只在於函數調用的處理。一般函數進行調用時,要將程序執行權轉到被調用函數中,然後再返回到調用它的函數中;而內聯函數在調用時,是將調用表達式用內聯函數體來替換。在使用內聯函數時,應注意如下幾點:
1.在內聯函數內不允許用循環語句和開關語句。
如果內聯函數有這些語句,則編譯將該函數視同普通函數那樣產生函數調用代碼,遞歸函數(自己調用自己的函數)是不能被用來做內聯函數的。內聯函數只適合於只有1~5行的小函數。對一個含有許多語句的大函數,函數調用和返回的開銷相對來說微不足道,所以也沒有必要用內聯函數實現。
2.內聯函數的定義必須出現在內聯函數第一次被調用之前。
3.本欄目講到的類結構中所有在類說明內部定義的函數是內聯函數。

『柒』 什麼叫內聯成員函數,代碼膨脹,剛學c++看什麼書好~我有一點c語言基礎

內聯函數如果要精確定義可以到MSDN上查詢

我只是大略跟你說明一下

你首先應該了解代碼復用性
由於我們在實現某個程序,而某個程序中存在某個功能會頻繁調用
我們就會把這個功能抽象成一個函數

每次調用普通函數,其實函數調用是一種軟中斷,每次調用的時候會進行現場保護
就是會保存如PSW的值 寄存器值
而函數返回之後就會恢復現場
這一些都需要CPU資源開銷

而內聯函數是一種與編譯器的約定,本來編譯器會根據你定義的函數
將每次調用該函數時都進行標記或是給一個地址值(實際上這個值是錯誤的,因為編譯器無法知道其運行時的地址,鏈接器做的工作)
而如果函數標記了內聯的話(inline),則編譯器會先進行性能判斷,如果OK則會將函數調用處的call指令到ret全部替換成你函數體的指令
也就是說 沒有調用該函數,而是直接執行函數體內部的代碼

而代碼膨脹一說,因為本來函數調用就是為了代碼復用
而你卻直接把函數的本體全部添加到調用處了 就好比你沒有寫這個函數 而是重復函數內部的執行代碼
如果你調用了100000次這樣的內聯函數
如果你每個函數內部都有10行的話
那麼你可以想像編譯器幫你復制粘貼了多少的代碼。。

自己的理解,不懂HI我

『捌』 內聯函數和成員函數的區別是什麼

內聯函數是指在調用衣櫃函數時,不把他當作調用而處理,而是把這個函數的代碼直接在調用他的函數里展開的形式,也可以理解為內聯函數就相當於一段代碼。不需要調用,效率就高些。成員函數是類中聲明的函數,屬於類。當然如果在類中定義的成員函數自動變為內聯函數。

『玖』 類體外定義成員函數和 內聯成員函數有什麼區別

  1. 內聯函數

  2. 在類聲明內定義內聯函數


  • 內聯函數

在C++中,用戶可以創建實際上不調用的短函數,他們的代碼在每次調用的程序行里得到擴展。這個過程類似於使用類似函數的宏。為使一個函數在程序行進行代碼擴展而不被調用,只要在函數前面加上關鍵字inline即可。

例如,在下面的程序,函數max()在行內擴展而不被調用:

#include<iostream>
usingnamespacestd;
inlineintmax(inta,intb)
{
returna>b?a:b;
}
intmain()
{
cout<<max(10,20);
cout<<""<<max(99,88);
}

上面的程序等價於下面的程序:

#include<iostream>
usingnamespacestd;
intmain()
{
cout<<(10>20?10:20);
cout<<""<<(99>88>99:88);
}

內聯函數是C++的一個重要補充的原因是,他們能使程序員寫出非常有效的代碼。因為類一般要求幾個經常被執行的介面函數,因此,這些函數的效率在C++中是非常重要的。我們知道,每次調用函數時,變元要進棧,各種寄存器內容要保存;函數返回時,又要恢復他們的內容。問題是這些指令要佔用時間。但是,如果函數在行內擴展,上述那些操作就不存在了。當然,雖然函數行內擴展能產生較快的速度,但由於重復編碼會產生較長的代碼,因此最好只內聯那些能明顯影響程序性能的函數。

inline對編譯器是一種請求,而不是命令。編譯器可以選擇忽略它。還有,一些編譯器不能內聯所有類型的函數。例如,通常編譯器不能內聯遞歸函數。必須查閱自己的編譯器用戶手冊以了解對內聯的限制。如果一個函數不能被內聯,它就被當作一個正常的函數調用。

inline關鍵字不是C++的 C子集 的一部分,因此,C89沒有定義它,然而,C99中增加了它。


內聯函數可以是類的成員。

classmyclass{
inta,b;
public:
voidinit(inti,intj);
voidshou();
};
inlinevoidmyclass::init(inti,intj)
{
a=i;
b=j;
}
inlinevoidmyclass::show()
{
cout<<a<<""<<b<<" ";
}
  • 在類聲明內定義內聯函數

在類聲明內(大括弧之內)定義內聯函數是可能的。如果一個函數是在類聲明內定義的,它將自動的轉換成內聯函數(如果可能的話)。沒有必要(但不是錯誤)在函數聲明的前面再加上關鍵字inline。

classmyclass{
inta,b;
public:
//automaticinline
voidinit(inti,intj){a=i;b=j;}
voidshow(){cout<<a<<""<<b<<" ";}
}

構造函數和析構函數也可以是內聯的。

——————————————————————————————————————————

參考文獻:

  1. C++參考大全(第四版)

熱點內容
php獲取ip伺服器 發布:2024-11-01 14:38:13 瀏覽:442
萬科海上傳奇二期 發布:2024-11-01 14:22:52 瀏覽:59
u盤文件夾是空的 發布:2024-11-01 14:19:57 瀏覽:402
python包含字元串 發布:2024-11-01 14:19:17 瀏覽:479
c語言的精華 發布:2024-11-01 14:19:02 瀏覽:588
steam截圖文件夾 發布:2024-11-01 14:18:59 瀏覽:613
ipad怎麼往安卓傳照片 發布:2024-11-01 14:18:19 瀏覽:508
我的電腦沒有文件夾選項 發布:2024-11-01 14:13:55 瀏覽:546
vb創建資料庫表 發布:2024-11-01 14:11:55 瀏覽:872
sql聯合表 發布:2024-11-01 14:03:25 瀏覽:962