C++11中內(nèi)聯(lián)函數(shù)(inline)用法實(shí)例
inline 是什么?
inline是C++ 11引入的關(guān)鍵字,在函數(shù)聲明or定義時(shí),返回類型前加上關(guān)鍵字inline,即可以把函數(shù)指定為內(nèi)聯(lián)函數(shù)。
引入inline的目的是什么?
目的是解決一些頻繁調(diào)用的函數(shù)大量消耗棧空間(棧內(nèi)存)的問題。另一方面用于替換C語(yǔ)言的宏(相比較宏是無(wú)法在進(jìn)行類型檢查)
內(nèi)聯(lián)函數(shù)的特點(diǎn)
- 內(nèi)聯(lián)函數(shù)的函數(shù)內(nèi)容本質(zhì)上是寫在調(diào)用內(nèi)聯(lián)函數(shù)的地方;
- 內(nèi)聯(lián)函數(shù)本質(zhì)上沒有入棧出棧的開銷;
- 和宏定義相比,內(nèi)聯(lián)函數(shù)更加安全,編譯器會(huì)根據(jù)函數(shù)的要求進(jìn)行嚴(yán)格的類型和作用域檢查,保證調(diào)用無(wú)誤;
- 內(nèi)聯(lián)函數(shù)一般上不包含循環(huán)、遞歸、switch或較長(zhǎng)的代碼 等復(fù)雜操作;
- 類聲明中定義的函數(shù),除虛函數(shù)外的其他函數(shù)都會(huì)自動(dòng)隱式地當(dāng)成內(nèi)聯(lián)函數(shù);
內(nèi)聯(lián)函數(shù)的寫法
這里的一個(gè)關(guān)鍵點(diǎn),inline必須與函數(shù)定義放在一起才能使函數(shù)成為內(nèi)聯(lián)函數(shù),僅將inline放在函數(shù)聲明前面不起任何作用。
inline是一種“用于實(shí)現(xiàn)”的關(guān)鍵字,不是一種“用于聲明”的關(guān)鍵字。
//在頭文件中可以進(jìn)行顯示聲明 //方式1 加 inline(建議使用) inline int TestFunc(int a, int b); //方式2 原始常見聲明方式 int TestFunc(int a, int b); //在源文件中定義 //正確 inline int TestFunc(int a, int b){ //do something return 0; } //錯(cuò)誤 int TestFunc(int a, int b){ //do something return 0; }
隱式內(nèi)聯(lián)和顯式內(nèi)聯(lián)
隱式內(nèi)聯(lián)的寫法
class CppObj { int TestFuncA() { return 0; } //隱式內(nèi)聯(lián) vitrual int TestFuncB() { return 0; } //虛函數(shù)不會(huì)進(jìn)行隱式內(nèi)聯(lián) }
顯式內(nèi)聯(lián)的寫法
class CppObj { int TestFuncA(); inline int TestFuncB(); vitrual int TestFuncC(); } inline int CppObj::TestFuncA() { //顯式內(nèi)聯(lián) return 0; } inline int CppObj::TestFuncB() { //顯式內(nèi)聯(lián) return 0; }
inline 函數(shù)的編譯器處理
inline函數(shù)僅僅是一個(gè)開發(fā)者對(duì)編譯器的建議,至于最后能否真正內(nèi)聯(lián),需要看編譯器的意思。如果編譯器判定函數(shù)不復(fù)雜,能在調(diào)用點(diǎn)展開,就會(huì)真正內(nèi)聯(lián)。
內(nèi)聯(lián)函數(shù)優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn)
- 內(nèi)聯(lián)函數(shù)相比宏函數(shù)來說,在代碼調(diào)用時(shí)會(huì)做安全檢查和類型轉(zhuǎn)換(同普通函數(shù)),而宏定義則不會(huì);
- 宏定義不可以在運(yùn)行時(shí)可調(diào)試,但內(nèi)聯(lián)函數(shù)可以;
- 內(nèi)聯(lián)函數(shù)同宏函數(shù)一樣會(huì)在被調(diào)用處進(jìn)行展開,無(wú)需參數(shù)壓棧、棧幀開辟與回收,結(jié)果返回等,從而能提高代碼的運(yùn)行速度。
- 缺點(diǎn)
- 代碼膨脹。內(nèi)聯(lián)是以代碼膨脹(復(fù)制)為代價(jià),是典型的以空間換時(shí)間的做法。
- 內(nèi)聯(lián)函數(shù)不可控。內(nèi)聯(lián)函數(shù)只是編碼者對(duì)編譯器的建議,是否對(duì)函數(shù)內(nèi)聯(lián),最終決定權(quán)在于編譯器。
- inline 函數(shù)無(wú)法隨著函數(shù)庫(kù)升級(jí)而升級(jí)。inline函數(shù)的改變需要重新編譯,不像 non-inline 可以直接鏈接。
虛函數(shù)可以是內(nèi)聯(lián)函數(shù)嗎?
- 虛函數(shù)可以是內(nèi)聯(lián)函數(shù);
- inline是可以修飾虛函數(shù);
虛函數(shù)內(nèi)聯(lián)條件?
可以內(nèi)聯(lián)的條件,編譯器具有實(shí)際對(duì)象而不是對(duì)象的指針或引用時(shí)才會(huì),所以當(dāng)虛函數(shù)表現(xiàn)多態(tài)性的時(shí)候不能內(nèi)聯(lián)。
虛函數(shù)表現(xiàn)多態(tài)性的時(shí)候不能內(nèi)聯(lián)
內(nèi)聯(lián)是在編譯期進(jìn)行的,但虛函數(shù)的多態(tài)性在運(yùn)行期,所以編譯器無(wú)法知曉運(yùn)行期具體調(diào)用哪個(gè)代碼
代碼釋義
#include <iostream> using namespace std; class Base { public: virtual ~Base() {} inline virtual void FuncName() { cout << "this is Base " << endl; } }; class Derived : public Base { public: inline virtual void FuncName() { cout << "this is Derived" << endl; } }; int main() { // 編譯器具有實(shí)際對(duì)象,所以它可以是內(nèi)聯(lián)的. Base b; b.FuncName(); // 編譯器具有對(duì)象的指針,呈現(xiàn)多態(tài)性,運(yùn)行時(shí)期才能確定,所以不能內(nèi)聯(lián)。 Base* p = new Derived(); p->FuncName(); delete p; p = nullptr; system("pause"); return 0; }
參考連接:
Are “inline virtual” member functions ever actually “inlined”?
總結(jié)
到此這篇關(guān)于C++11中內(nèi)聯(lián)函數(shù)(inline)用法的文章就介紹到這了,更多相關(guān)C++11內(nèi)聯(lián)函數(shù)inline內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中pthread_exit()函數(shù)實(shí)現(xiàn)終止線程
本文主要介紹了C語(yǔ)言中pthread_exit()函數(shù)實(shí)現(xiàn)終止線程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05C語(yǔ)言實(shí)現(xiàn)商品管理系統(tǒng)開發(fā)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)商品管理系統(tǒng)開發(fā),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08C語(yǔ)言調(diào)用SQLite數(shù)據(jù)庫(kù)實(shí)現(xiàn)數(shù)據(jù)增刪改查
SQLite是一種輕量級(jí)的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),是一個(gè)開源的、零配置的、服務(wù)器端的、自包含的、零管理的、事務(wù)性的SQL數(shù)據(jù)庫(kù)引擎,本文主要介紹了如何調(diào)用SQLite數(shù)據(jù)庫(kù)實(shí)現(xiàn)數(shù)據(jù)增刪改查,需要的可以參考一下2023-08-08判斷指定的進(jìn)程或程序是否存在方法小結(jié)(vc等)
VC判斷進(jìn)程是否存在?比如我想知道記事本是否運(yùn)行,要用到哪些函數(shù)等實(shí)例,需要的朋友可以參考下2013-01-01C語(yǔ)言指針應(yīng)用簡(jiǎn)單實(shí)例
這篇文章主要介紹了C語(yǔ)言指針應(yīng)用簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05Qt利用QDrag實(shí)現(xiàn)拖拽拼圖功能詳解
QDrag類為MIME-based拖拽數(shù)據(jù)轉(zhuǎn)換提供支持。本文為大家主要介紹如何利用QDrag類實(shí)現(xiàn)拖拽拼圖功能。左邊是打散的圖,拖動(dòng)到右邊進(jìn)行復(fù)現(xiàn),此外程序還支持手動(dòng)拖入原圖片,感興趣的可以了解一下2022-07-07C++中POCO庫(kù)的安裝與基礎(chǔ)知識(shí)介紹(Windwos和Linux)
這篇文章主要為大家介紹了C++ POCO庫(kù)的簡(jiǎn)單介紹、下載以及安裝方式、簡(jiǎn)單代碼示例,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-05-05