close

最近表示有點... 無聊吧XD

不能停止學習啊~ 慢慢學慢慢進步吧~

 

除了學習有點停止之外,最近也體認到了一些... 人際關係上的問題吧

真的是活越久看得越多啊... 人這種生物真的很奇妙

明明以前是個單純善良的人,開始健身會打扮、賺了點錢,有女森開始貼上來之後,就變成另外一個人了

充滿了心機與自以為是的態度卻渾然不覺... 還講的自己像個聖人一樣

我看了真的只能搖頭,跟他講他還會覺得自己沒問題 (攤手

 

果然有自信之餘,也不能忘記自己原本的樣子啊

我還是繼續當那個我認為很弱小的同學好了

我只能好好鞭策自己成為好的那一種,不好的就當作警惕並遠離吧

 

回到正題,今天來看的是callback function

這個東西說白了就是利用"函式指標"來讓物件之間能夠傳送資料或是進行溝通

比如說今天有一個server和client,我們要讓server在某些情況下去通知client來做一些事情

當然我第一個會想到用觀察者模式啦... 但那也是一個方法就是了

如果是在兩個不同的模組,比如說在兩個dll裡的物件,用callback funtion就是相對方便的一種選擇

(前東家的專案裡就有這種作法)

 

比較傳統的方式呢,就是在server裡面定義一個callback function的長相,並且設定一個member

大概像是這樣:

typedef void (*pClientCallbackFunc)(int);

class server {

public:

    void setCallbackFunc(pClientCallbackFunc callbackfunc);

    void callback2Client(int i);

private:

    pClientCallbackFunc m_callbackFunc;

}

這樣就有一個callback的member了,而他的長相就是typedef的那樣,就是一個長那樣的函式指標

而client呢可能就是長這個樣子:

class client {

public:

    static void callbackFunc(int i) {

        cout << "callback : " << i << endl;

    }

}

然後怎麼把client的callbackFunc設定到server呢,簡單說就是把client的callbackFunc的指標存到server的m_calbackFunc的地方

這樣server就可以去呼叫client的callbackFunc了:

void setCallbackFunc(pClientCallbackFunc callbackfunc) {

    m_calbackFunc = callbackfunc;

}

 

這邊特別提一下,如果client的callbackFunc(int i)不是static,然後把它設定進去的話,編譯器就會告訴你有error...

因為在C++裡面有一些特性的關係,這個callbackfunc只能是一個static member function

原因大概是在C++中在呼叫member function的時候其實會偷偷用到this這個指標,也就是物件本身

必須要有物件本身的指標才能呼叫那個物件的member function

所以在編譯的時候用上述的寫法其實是沒辦法符合這個規定的,因此會跳出error

(但其實比較新版的C++已經可以輕鬆解決這件事了,稍後會提到)

 

一個可行的方式就是將那個member function設成static member function

因為static member function就是所有這個class共用的,因此在呼叫的時候並不需要this

所以callback2Client大概是長這樣:

void callback2Client(int i) {

    m_callbackFunc(i);

}

這樣在setCallbackFunc(&client::callbackFunc)之後,就可以使用callback了

 

但這邊有另一個問題,如果我在callback的時候想使用client這個物件的member要怎麼辦呢

這時候就要用一點小技巧,也就是在setCallbackFunc的時候把client的指標傳進去並存起來:

void setCallbackFunc(pClientCallbackFunc callbackfunc, void* this_ptr) {

    m_client = static_cast<client*>(this_ptr);

    m_calbackFunc = callbackfunc;

}

 

這個m_client的型態就是client*,也就是一個指標,是server的一個member

這樣在callback2Client的時候,就可以去使用一些client物件的member:

void callback2Client(int i) {

    m_callbackFunc(i);

    // m_client-> ....

}

 

大概就是這樣吧,雖然說這是很舊的用法,之後大概沒機會用到,不過有些觀念還滿有趣的

下一篇會用比較新的方式來實作,比較簡單也明瞭,就之後再說吧

 

 

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 頁頁頁六滴 的頭像
    頁頁頁六滴

    人森很精彩,所以要把所有事情都記起來=ˇ=

    頁頁頁六滴 發表在 痞客邦 留言(0) 人氣()