欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++知識點之inline函數(shù)、回調(diào)函數(shù)和普通函數(shù)

 更新時間:2021年07月12日 10:28:41   作者:李春港  
這篇文章主要給大家介紹了關(guān)于C++知識點之inline函數(shù)、回調(diào)函數(shù)和普通函數(shù)的相關(guān)使用方法,以及回調(diào)函數(shù)和普通函數(shù)的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下

一、inline內(nèi)聯(lián)函數(shù)#

特征

  • 相當(dāng)于把內(nèi)聯(lián)函數(shù)里面的內(nèi)容寫在調(diào)用內(nèi)聯(lián)函數(shù)處;
  • 相當(dāng)于不用執(zhí)行進入函數(shù)的步驟,直接執(zhí)行函數(shù)體;
  • 相當(dāng)于宏,卻比宏多了類型檢查,真正具有函數(shù)特性;
  • 編譯器一般不內(nèi)聯(lián)包含循環(huán)、遞歸、switch 等復(fù)雜操作的內(nèi)聯(lián)函數(shù);
  • 在類聲明中定義的函數(shù),除了虛函數(shù)的其他函數(shù)都會自動隱式地當(dāng)成內(nèi)聯(lián)函數(shù);
  • 內(nèi)聯(lián)關(guān)鍵字是在編譯時建議編譯器內(nèi)聯(lián),是不是內(nèi)聯(lián)函數(shù)取決于編譯器,一個好的編譯器將會根據(jù)函數(shù)的定義體,自動地取消不值得的內(nèi)聯(lián)(是否內(nèi)聯(lián):1、可以通過多次調(diào)用函數(shù),查看執(zhí)行文件大小,如果變大了,就證明是內(nèi)聯(lián)函數(shù);2、通過反匯編查看數(shù)據(jù))。

1.1 使用#

  • inline是一種“用于實現(xiàn)的關(guān)鍵字”,而不是一種“用于聲明的關(guān)鍵字”,也就是說,如果只在生命中使用inline是沒有用的,若要成為inline函數(shù)必須在定義函數(shù)的時候添加該關(guān)鍵字。在聲明中加不加inline關(guān)鍵字都沒關(guān)系,但是為了閱讀方便,還是建議聲明和定義都加上;
  • C++在類中定義函數(shù)的時候,當(dāng)函數(shù)不包含循環(huán)、遞歸、switch 等復(fù)雜操作時,編譯器會進行隱式內(nèi)聯(lián)。
  • C++在類外定義函數(shù),因為與非inline函數(shù)不同:inline函數(shù)對編譯器而言必須是可見的,以便它能夠在調(diào)用點展開該函數(shù),inline函數(shù)必須在調(diào)用該函數(shù)的每個文本文件中定義。所以內(nèi)聯(lián)函數(shù)的聲明和定義建議都放在同一個頭文件,這樣另一個.cpp文件#include該頭文件的時候,就把該內(nèi)聯(lián)函數(shù)的定義也包含進來了,這就可以正常使用內(nèi)聯(lián)函數(shù)了。

聲明

// 聲明1(加 inline,建議使用)
inline int functionName(int first, int second,...);

定義

// 定義
inline int functionName(int first, int second,...) {/****/};

類內(nèi)定義

// 類內(nèi)定義,隱式內(nèi)聯(lián)
class A {
int doA() { return 0; } // 隱式內(nèi)聯(lián)
}

類外定義

// 類外定義,需要顯式內(nèi)聯(lián)
class A {
int doA();
}
inline int A::doA() { return 0; } // 需要顯式內(nèi)聯(lián)

1.2 編譯器對 inline 函數(shù)處理步驟#

  • 將 inline 函數(shù)體復(fù)制到 inline 函數(shù)調(diào)用點處;
  • 為所用 inline 函數(shù)中的局部變量分配內(nèi)存空間;
  • 將 inline 函數(shù)的的輸入?yún)?shù)和返回值映射到調(diào)用方法的局部變量空間中;
  • 如果 inline 函數(shù)有多個返回點,將其轉(zhuǎn)變?yōu)?inline 函數(shù)代碼塊末尾的分支(使用 GOTO)。

1.3 優(yōu)缺點#

1.3.1 優(yōu)點#

  • 內(nèi)聯(lián)函數(shù)同宏函數(shù)一樣將在被調(diào)用處進行代碼展開,省去了參數(shù)壓棧、棧幀開辟與回收,結(jié)果返回等,從而提高程序運行速度。
  • 內(nèi)聯(lián)函數(shù)相比宏函數(shù)來說,在代碼展開時,會做安全檢查或自動類型轉(zhuǎn)換(同普通函數(shù)),而宏定義則不會。
  • 在類中聲明同時定義的成員函數(shù),自動轉(zhuǎn)化為內(nèi)聯(lián)函數(shù),因此內(nèi)聯(lián)函數(shù)可以訪問類的成員變量,宏定義則不能。
  • 內(nèi)聯(lián)函數(shù)在運行時可調(diào)試,而宏定義不可以。

1.3.2 慎用內(nèi)聯(lián)#

  • 內(nèi)聯(lián)是以代碼膨脹為代價,僅僅是省去了函數(shù)調(diào)用的開銷,從而提高了函數(shù)的執(zhí)行效率。如果執(zhí)行函數(shù)體內(nèi)代碼的時間,相比于函數(shù)調(diào)用的開銷較大,那么效率的收獲會很小。另一個方面,每一處內(nèi)聯(lián)函數(shù)調(diào)用都要復(fù)制代碼,將使程序總代碼量增大,消耗更多的內(nèi)存空間。
  • 類的構(gòu)造函數(shù)和析構(gòu)函數(shù)容易讓人誤解成使用內(nèi)聯(lián)函數(shù)更有效。要當(dāng)心構(gòu)造函數(shù)和析構(gòu)函數(shù)可能會隱藏一些行為,如”偷偷地“執(zhí)行基類或成員對象的構(gòu)造函數(shù)和析構(gòu)函數(shù)。所以不要隨便地將構(gòu)造函數(shù)和析構(gòu)函數(shù)的定義體放在類的定義中。

1.3.3 不宜使用內(nèi)聯(lián)#

  • 如果函數(shù)體內(nèi)的代碼比較長,使用內(nèi)聯(lián)將導(dǎo)致內(nèi)存消耗代價比較高;
  • 如果函數(shù)體內(nèi)出現(xiàn)循環(huán),那么執(zhí)行函數(shù)體內(nèi)代碼的時間要比函數(shù)調(diào)用的開銷大;

1.4 虛函數(shù)(virtual)可以是內(nèi)聯(lián)函數(shù)(inline)嗎?#

  • 虛函數(shù)可以是內(nèi)聯(lián)函數(shù),內(nèi)聯(lián)是可以修飾虛函數(shù)的,但是當(dāng)虛函數(shù)表現(xiàn)多態(tài)性的時候不能內(nèi)聯(lián)。
  • 內(nèi)聯(lián)是在編譯器建議編譯器內(nèi)聯(lián),而虛函數(shù)的多態(tài)性在運行期,編譯器無法知道運行期調(diào)用哪個代碼,因此虛函數(shù)表現(xiàn)為多態(tài)性時(運行期)不可以內(nèi)聯(lián)。
  • inline virtual 唯一可以內(nèi)聯(lián)的時候是:編譯器知道所調(diào)用的對象是哪個類(如 Base::who()),這只有在編譯器具有實際對象而不是對象的指針或引用時才會發(fā)生。

如下例程:

#include <iostream>
using namespace std;
class Base
{
    public:
    inline virtual void who()
    {
        cout << "I am Base\n";
    }
    virtual ~Base() {}
};
    
class Derived : public Base
{
    public:
    inline void who() // 不寫inline時隱式內(nèi)聯(lián)
    {
        cout << "I am Derived\n";
    }
};

int main()
{
// 此處的虛函數(shù) who(),是通過類(Base)的具體對象(b)來調(diào)用的,編譯期間就能確定了,所以它可以是內(nèi)聯(lián)的,但最終是否內(nèi)聯(lián)取決于編譯器。
Base b;
b.who();

// 此處的虛函數(shù)是通過指針調(diào)用的,呈現(xiàn)多態(tài)性,需要在運行時期間才能確定,所以不能為內(nèi)聯(lián)。
Base *ptr = new Derived();
ptr->who();

// 因為Base有虛析構(gòu)函數(shù)(virtual ~Base() {}),所以 delete 時,會先調(diào)用派生類(Derived)析構(gòu)函數(shù),再調(diào)用基類(Base)析構(gòu)函數(shù),防止內(nèi)存泄漏。
delete ptr;
ptr = nullptr;

system("pause");
return 0;
}

二、回調(diào)函數(shù)和普通函數(shù)#

更詳細的回調(diào)函數(shù)理解可以查看本地的這個文章【【知識點】10張圖讓你徹底理解回調(diào)函數(shù)】

2.1 什么是回調(diào)函數(shù)?#

把a函數(shù)指針像參數(shù)傳遞那樣傳給b函數(shù),而這個a函數(shù)會在某個時刻被b函數(shù)調(diào)用執(zhí)行,這就叫做回調(diào),a函數(shù)稱為回調(diào)函數(shù)。如果回調(diào)函數(shù)立即被執(zhí)行就稱為同步回調(diào),如果在之后晚點的某個時間再執(zhí)行,則稱之為異步回調(diào)。

2.2 為什么要使用回調(diào)函數(shù)?#

先拋出答案:回調(diào)函數(shù)的好處和作用,那就是解耦,對,就是這么簡單的答案,就是因為這個特點,普通函數(shù)代替不了回調(diào)函數(shù)。

如下代碼:

int Callback_1()
{
    printf("Hello");
    printf("This is Callback_1 "); 
    return 0;
}

int Callback_2() 
{
    printf("Hello");
    printf("This is Callback_2 ");    
    return 0;
}

發(fā)現(xiàn)以上代碼是可以解耦的,因為兩個函數(shù)都執(zhí)行了printf("Hello"),這個時候我們可以通過回調(diào)的方式進行解耦,如下:

#include<stdio.h>

int Callback_1()    // Callback Function 1
{
    printf("This is Callback_1 "); 
    return 0;
}

int Callback_2()    // Callback Function 2
{    
    printf("This is Callback_2 ");    
    return 0;
}

int Handle(int (*Callback)())
{    
    printf("Entering Handle Function. ");    
    Callback();    
    printf("Leaving Handle Function. ");
}

int main()
{    
    printf("Entering Main Function. ");    
    Handle(Callback_1);    
    Handle(Callback_2);  
    printf("Leaving Main Function. ");    
    return 0;
}

像這樣我們就減少了重復(fù)代碼啦,也就是解耦。這是使用普通函數(shù)調(diào)用無法做到的。

回調(diào)函數(shù)和普通函數(shù)有什么區(qū)別?

1、對普通函數(shù)的調(diào)用:調(diào)用程序發(fā)出對普通函數(shù)的調(diào)用后,程序執(zhí)行立即轉(zhuǎn)向被調(diào)用函數(shù)執(zhí)行,直到被調(diào)用函數(shù)執(zhí)行完畢后,再返回調(diào)用程序繼續(xù)執(zhí)行。從發(fā)出調(diào)用的程序的角度看,這個過程為“調(diào)用-->等待被調(diào)用函數(shù)執(zhí)行完畢-->繼續(xù)執(zhí)行”。

2、對回調(diào)函數(shù)調(diào)用:調(diào)用程序發(fā)出對回調(diào)函數(shù)的調(diào)用后,不等函數(shù)執(zhí)行完畢,立即返回并繼續(xù)執(zhí)行。這樣,調(diào)用程序執(zhí)和被調(diào)用函數(shù)同時在執(zhí)行。當(dāng)被調(diào)函數(shù)執(zhí)行完畢后,被調(diào)函數(shù)會反過來調(diào)用某個事先指定函數(shù),以通知調(diào)用程序:函數(shù)調(diào)用結(jié)束。這個過程稱為回調(diào)(Callback),這正是回調(diào)函數(shù)名稱的由來。

總結(jié)

到此這篇關(guān)于C++知識點之inline函數(shù)、回調(diào)函數(shù)和普通函數(shù)的文章就介紹到這了,更多相關(guān)inline函數(shù)、回調(diào)函數(shù)和普通函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Matlab實現(xiàn)別踩白塊小游戲的示例代碼

    Matlab實現(xiàn)別踩白塊小游戲的示例代碼

    別踩白塊是一款音樂類休閑游戲,游戲的玩法不難,只需跟著音樂的節(jié)奏點中對的方塊即可。本文將用Matlab實現(xiàn)這一經(jīng)典游戲,感興趣的可以了解一下
    2022-03-03
  • C語言實現(xiàn)循環(huán)鏈表

    C語言實現(xiàn)循環(huán)鏈表

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)循環(huán)鏈表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • C++利用GPAC實現(xiàn)生成MP4文件的示例代碼

    C++利用GPAC實現(xiàn)生成MP4文件的示例代碼

    GPAC主要針對學(xué)生和內(nèi)容創(chuàng)作者,代表了一個跨平臺的多媒體框架,開發(fā)人員可以使用它在?LGPL?許可下制作開源媒體。本文就來用GPAC實現(xiàn)生成MP4文件,感興趣的可以了解一下
    2023-02-02
  • C++11新特性之a(chǎn)uto的使用

    C++11新特性之a(chǎn)uto的使用

    熟悉腳本語言的人都知道,很多腳本語言都引入了“類型自動推斷”技術(shù):比如Python,可以直接聲明變量,在運行時進行類型檢查。隨著C++11標準的發(fā)布,C++語言也引入了類型自動推斷的功能。這篇文章主要介紹了C++11新特性之a(chǎn)uto的使用,有需要的朋友們可以參考借鑒。
    2016-12-12
  • C++實現(xiàn)校園導(dǎo)游系統(tǒng)

    C++實現(xiàn)校園導(dǎo)游系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)校園導(dǎo)游系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C++ 的三種訪問權(quán)限與三種繼承方式

    C++ 的三種訪問權(quán)限與三種繼承方式

    我們知道C++中的類,有三種訪問權(quán)限(也稱作訪問控制),它們分別是public、protected、private,C++中繼承的方式還有多種。下面通過本文給大家詳細介紹,對c++中的訪問權(quán)限和繼承方式感興趣的朋友一起看看吧
    2016-11-11
  • C 轉(zhuǎn)移表/轉(zhuǎn)換表的深入分析

    C 轉(zhuǎn)移表/轉(zhuǎn)換表的深入分析

    本篇文章是對c語言中轉(zhuǎn)移表/轉(zhuǎn)換表進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++筆記之std::future的用法小結(jié)

    C++筆記之std::future的用法小結(jié)

    std::future通常由某個Provider創(chuàng)建,與std::async一起使用,本文主要介紹了C++筆記之std::future的用法小結(jié),具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • C++筆記-設(shè)置cout輸出數(shù)據(jù)的寬度和填充方式

    C++筆記-設(shè)置cout輸出數(shù)據(jù)的寬度和填充方式

    這篇文章主要介紹了C++筆記-設(shè)置cout輸出數(shù)據(jù)的寬度和填充方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語言實現(xiàn)數(shù)據(jù)的壓縮與解壓

    C語言實現(xiàn)數(shù)據(jù)的壓縮與解壓

    數(shù)據(jù)壓縮是通過一系列的算法和技術(shù)將原始數(shù)據(jù)轉(zhuǎn)換為更緊湊的表示形式,以減少數(shù)據(jù)占用的存儲空間,數(shù)據(jù)解壓縮則是將壓縮后的數(shù)據(jù)恢復(fù)到原始的表示形式,本文給大家詳細介紹了C語言實現(xiàn)數(shù)據(jù)壓縮與解壓,需要的朋友可以參考下
    2023-08-08

最新評論