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

C++基礎(chǔ)入門教程(九):函數(shù)指針之回調(diào)

 更新時(shí)間:2014年11月17日 10:23:58   投稿:junjie  
這篇文章主要介紹了C++基礎(chǔ)入門教程(九):函數(shù)指針之回調(diào),本文講解了函數(shù)的地址、聲明函數(shù)指針、歷史原因、typedef挽救復(fù)雜的函數(shù)指針等內(nèi)容,需要的朋友可以參考下

在Java,要實(shí)現(xiàn)某個(gè)時(shí)間調(diào)用某段代碼,是很簡單的事情,那就是使用接口。
而在C++里,有一個(gè)比較高深的方式,那就是使用函數(shù)指針。

比如Cocos2d-x的定時(shí)器(schedule)、消息訂閱(NotificationCenter)都使用了函數(shù)指針來完成回調(diào)的功能。
這也是為什么我們總是能把某個(gè)函數(shù)作為參數(shù)傳進(jìn)去,然后在某個(gè)時(shí)刻這個(gè)函數(shù)會(huì)被調(diào)用。

一、函數(shù)的地址

要獲取一個(gè)int變量的地址很簡單,比如int num; 那么num的地址就是&num。
而獲取函數(shù)的地址更簡單,函數(shù)的名字就是函數(shù)的地址,如下代碼:

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

void hello();
int _tmain(int argc, _TCHAR* argv[])
{
    auto p = hello;
    p();
    return 0;
}
void hello()
{
    cout << "helloworld";
}

我們定義了一個(gè)hello函數(shù),然后直接把函數(shù)名字賦值給指針p,于是,就可以把p當(dāng)成了hello函數(shù)來使用了。
這很簡單吧。

二、聲明函數(shù)指針

獲取函數(shù)的地址很簡單,但是,如何聲明函數(shù)指針就變得不那么簡單了。
我們總不能每次都使用auto來逃避吧?有時(shí)候我們不得不顯式地聲明函數(shù)指針,那么,如何聲明呢?
還記得我們說過的typedef定義類型別名嗎?函數(shù)指針的聲明也是一樣的規(guī)則,先聲明一個(gè)函數(shù),如:void hello();
然后把函數(shù)名字換成指針,如:void (*p)();

沒錯(cuò),就是這么簡單,void (*p)(); 就是void hello(); 的聲明了。
立刻再來試試,這個(gè)函數(shù):int getValue(float dt);
它的函數(shù)指針聲明是什么?沒錯(cuò),就是:int (*p) getValue(float dt);

沒錯(cuò),就是這么簡單int getValue(float dt); 就是int (*p) getValue(float dt);的函數(shù)指針聲明了。
立刻再來試試,這..(小若:停~!別以為我不在你就可以亂來?。?/p>

好吧,那就不繼續(xù)試了,我們來看看,剛剛那段代碼可以這樣寫:

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

void hello();
int _tmain(int argc, _TCHAR* argv[])
{
    void (*p)();
    p = hello;
    p();
    (*p)(); // 偷偷加了這句
    return 0;
}
void hello()
{
    cout << "helloworld";
}

好了,很簡單,不多說了~
另外,有沒有發(fā)現(xiàn)我偷偷又加了一句代碼?
沒錯(cuò),用(*p)();的方式也通過能成功調(diào)用hello函數(shù),這是為什么呢?

三、歷史原因

由于p是指針,它指向的是hello函數(shù)的地址,所以,*p就代表hello函數(shù),于是,(*p)()就等于hello(),這是正常的邏輯。
所以,其實(shí)(*p)()才是比較正常的調(diào)用方式。
 
然而,由于函數(shù)名本來就是指向了函數(shù)的指針,也就是說,hello其實(shí)也是指向了函數(shù)的地址。
換句話說,p和hello其實(shí)都是指針,那么,p的調(diào)用方式和hello的調(diào)用方式應(yīng)該也是一樣的,于是,p()就相當(dāng)于hello()。
 
這兩種方式都是正確的,其實(shí)語法這東西,就是人定的,歷史上前輩對(duì)這兩種方式各持所見,于是就容忍了這兩種看似沖突的方式同時(shí)存在了。
 
不過,我想,大部分人都會(huì)更喜歡直接用p(),而不是(*p)()吧。

四、typedef挽救復(fù)雜的函數(shù)指針

如下代碼:

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

string hehe1(int num, float value);
string hehe2(int num, float value);
string hehe3(int num, float value);

int _tmain(int argc, _TCHAR* argv[])
{
    /* 聲明函數(shù)指針數(shù)組 */
    string(*p[3])(int num, float value) = {hehe1, hehe2, hehe3};

    string result = p[1](1, 2);
    cout << result.c_str() << endl;
    return 0;
}

string hehe1(int num, float value)
{
    return "haha1";
}
string hehe2(int num, float value)
{
    return "haha2";
}
string hehe3(int num, float value)
{
    return "haha3";
}

這段代碼有三個(gè)參數(shù)和返回值都相同的函數(shù),分別是hehe1、hehe2、hehe3
然后,我們要聲明一個(gè)數(shù)組,這個(gè)數(shù)組用來存放這三個(gè)函數(shù)指針。
這里的函數(shù)還算是比較簡單的,所以看起來不算復(fù)雜。
但如果這樣的聲明出現(xiàn)太多的話,未免會(huì)讓人很沮喪。

于是,typedef挽救了我們,我們可以復(fù)雜的聲明變成這樣:

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

int _tmain(int argc, _TCHAR* argv[])
{
    /* 用HeheFunc來代替復(fù)雜的函數(shù)聲明 */
    typedef string(*HeheFunc)(int num, float value);
    /* 聲明函數(shù)指針數(shù)組 */
    HeheFunc p[3] = { hehe1, hehe2, hehe3 };
    string result = p[1](1, 2);
    cout << result.c_str() << endl;
    return 0;
}

使用typedef代替函數(shù)聲明之后,我們就能很輕松地使用它,并且會(huì)讓我們的代表變得很簡單,很好理解。
現(xiàn)在,HeheFunc就代表了一種類型,什么類型呢?就是參數(shù)為(int num, float value),返回值為string的函數(shù)類型。

五、結(jié)束

好了,就嘮叨這么多吧。

相關(guān)文章

  • C語言設(shè)計(jì)實(shí)現(xiàn)掃描器的自動(dòng)機(jī)的示例詳解

    C語言設(shè)計(jì)實(shí)現(xiàn)掃描器的自動(dòng)機(jī)的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言設(shè)計(jì)實(shí)現(xiàn)掃描器的自動(dòng)機(jī),可識(shí)別的單詞包括:關(guān)鍵字、界符、標(biāo)識(shí)符和常整型數(shù),感興趣的小伙伴可以了解一下
    2022-12-12
  • 用C語言實(shí)現(xiàn)五子棋小游戲

    用C語言實(shí)現(xiàn)五子棋小游戲

    這篇文章主要為大家詳細(xì)介紹了用C語言實(shí)現(xiàn)五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C語言圖書借閱系統(tǒng)源碼

    C語言圖書借閱系統(tǒng)源碼

    這篇文章主要為大家分享了C語言圖書借閱系統(tǒng)源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C語言項(xiàng)目小學(xué)生數(shù)學(xué)考試系統(tǒng)參考

    C語言項(xiàng)目小學(xué)生數(shù)學(xué)考試系統(tǒng)參考

    今天小編就為大家分享一篇關(guān)于C語言項(xiàng)目小學(xué)生數(shù)學(xué)考試系統(tǒng)參考,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • C++實(shí)現(xiàn)LeetCode(100.判斷相同樹)

    C++實(shí)現(xiàn)LeetCode(100.判斷相同樹)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(100.判斷相同樹),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++連接并使用MySQL數(shù)據(jù)庫

    C++連接并使用MySQL數(shù)據(jù)庫

    這篇文章主要為大家詳細(xì)介紹了C++連接并使用MySQL數(shù)據(jù)庫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • C語言隊(duì)列和應(yīng)用詳情

    C語言隊(duì)列和應(yīng)用詳情

    這篇文章主要介紹了C語言隊(duì)列和應(yīng)用詳情,文章將讓大家掌握掌握隊(duì)列的原理和作用、掌握隊(duì)列的寫法、掌握隊(duì)列在產(chǎn)品中的應(yīng)用,需要的朋友可以參考一下
    2022-03-03
  • C++使用標(biāo)準(zhǔn)庫實(shí)現(xiàn)事件和委托以及信號(hào)和槽機(jī)制

    C++使用標(biāo)準(zhǔn)庫實(shí)現(xiàn)事件和委托以及信號(hào)和槽機(jī)制

    這篇文章主要為大家詳細(xì)介紹了C++如何使用標(biāo)準(zhǔn)庫實(shí)現(xiàn)事件和委托以及信號(hào)和槽機(jī)制,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2022-11-11
  • C++實(shí)現(xiàn)線性表鏈?zhǔn)酱鎯?chǔ)(單鏈)

    C++實(shí)現(xiàn)線性表鏈?zhǔn)酱鎯?chǔ)(單鏈)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)線性表鏈?zhǔn)酱鎯?chǔ),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C++使用gtest框架編寫單元測試的教程詳解

    C++使用gtest框架編寫單元測試的教程詳解

    gtest 是 Google 開發(fā)的一個(gè)用于 C++ 的測試框架,廣泛應(yīng)用于編寫和運(yùn)行單元測試,并且支持任何類型的測試,而不僅僅是單元測試,本文本文給大家介紹了C++使用gtest框架編寫單元測試的教程,需要的朋友可以參考下
    2024-08-08

最新評(píng)論

溧阳市| 梧州市| 杭州市| 缙云县| 岗巴县| 开江县| 开鲁县| 鄄城县| 瑞金市| 湘阴县| 永济市| 淄博市| 龙州县| 乌拉特中旗| 开封市| 武隆县| 阿合奇县| 宁陕县| 合川市| 平安县| 广昌县| 郓城县| 云霄县| 会同县| 元谋县| 安化县| 奉新县| 额尔古纳市| 陆丰市| 丹棱县| 兴安县| 孝昌县| 乐昌市| 察雅县| 乌兰县| 呼和浩特市| 普安县| 盐山县| 亚东县| 陆河县| 龙井市|