程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++基本入門教程(九):函數指針之回調

C++基本入門教程(九):函數指針之回調

編輯:關於C++

C++基本入門教程(九):函數指針之回調。本站提示廣大學習愛好者:(C++基本入門教程(九):函數指針之回調)文章只能為提供參考,不一定能成為您想要的結果。以下是C++基本入門教程(九):函數指針之回調正文


在Java,要完成某個時光挪用某段代碼,是很簡略的工作,那就是應用接口。
而在C++裡,有一個比擬精深的方法,那就是應用函數指針。

好比Cocos2d-x的准時器(schedule)、新聞定閱(NotificationCenter)都應用了函數指針來完成回調的功效。
這也是為何我們老是能把某個函數作為參數傳出來,然後在某個時辰這個函數會被挪用。

1、函數的地址

要獲得一個int變量的地址很簡略,好比int num; 那末num的地址就是&num。
而獲得函數的地址更簡略,函數的名字就是函數的地址,以下代碼:


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

我們界說了一個hello函數,然後直接把函數名字賦值給指針p,因而,便可以把p當做了hello函數來應用了。
這很簡略吧。

2、聲明函數指針

獲得函數的地址很簡略,然則,若何聲明函數指針就變得不那末簡略了。
我們總不克不及每次都應用auto來回避吧?有時刻我們不能不顯式地聲明函數指針,那末,若何聲明呢?
還記得我們說過的typedef界說類型別號嗎?函數指針的聲明也是一樣的規矩,先聲明一個函數,如:void hello();
然後把函數名字換成指針,如:void (*p)();

沒錯,就是這麼簡略,void (*p)(); 就是void hello(); 的聲清楚明了。
連忙再來嘗嘗,這個函數:int getValue(float dt);
它的函數指針聲明是甚麼?沒錯,就是:int (*p) getValue(float dt);

沒錯,就是這麼簡略int getValue(float dt); 就是int (*p) getValue(float dt);的函數指針聲清楚明了。
連忙再來嘗嘗,這..(小若:停~!別認為我不在你便可以糊弄!)

好吧,那就不持續試了,我們來看看,方才那段代碼可以如許寫:


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

好了,很簡略,不多說了~
別的,有無發明我偷偷又加了一句代碼?
沒錯,用(*p)();的方法也經由過程能勝利挪用hello函數,這是為何呢?

3、汗青緣由

因為p是指針,它指向的是hello函數的地址,所以,*p就代表hello函數,因而,(*p)()就等於hello(),這是正常的邏輯。
所以,其實(*p)()才是比擬正常的挪用方法。
 
但是,因為函數名原來就是指向了函數的指針,也就是說,hello其實也是指向了函數的地址。
換句話說,p和hello其實都是指針,那末,p的挪用方法和hello的挪用方法應當也是一樣的,因而,p()就相當於hello()。
 
這兩種方法都是准確的,其實語法這器械,就是人定的,汗青上先輩對這兩種方法各持所見,因而就容忍了這兩種看似抵觸的方法同時存在了。
 
不外,我想,年夜部門人都邑更愛好直接用p(),而不是(*p)()吧。

4、typedef搶救龐雜的函數指針

以下代碼:

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

int _tmain(int argc, _TCHAR* argv[])
{
    /* 聲明函數指針數組 */
    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";
}

這段代碼有三個參數和前往值都雷同的函數,分離是hehe1、hehe2、hehe3
然後,我們要聲明一個數組,這個數組用來寄存這三個函數指針。
這裡的函數還算是比擬簡略的,所以看起來不算龐雜。
但假如如許的聲明湧現太多的話,不免難免會讓人很懊喪。

因而,typedef搶救了我們,我們可以龐雜的聲明釀成如許:


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

應用typedef取代函數聲明以後,我們就可以很輕松地應用它,而且會讓我們的代表變得很簡略,很好懂得。
如今,HeheFunc就代表了一品種型,甚麼類型呢?就是參數為(int num, float value),前往值為string的函數類型。

5、停止

好了,就絮聒這麼多吧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved