日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++中std::tr1::function和bind 组件的使用

發(fā)布時間:2023/12/10 c/c++ 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++中std::tr1::function和bind 组件的使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在C++的TR1中(Technology Report)中包含一個function模板類和bind模板函數(shù),使用它們可以實現(xiàn)類似函數(shù)指針的功能,但卻卻比函數(shù)指針更加靈活,特別是函數(shù)指向類的非靜態(tài)成員函數(shù)時。可以參考Scott Meyers. <<Effective C++ (3rd Edition)>>. Item 35.下面具體說明其使用方法。

一、指向全局函數(shù)或靜態(tài)成員函數(shù)時

因為在本質(zhì)上講全局函數(shù)和靜態(tài)成員函數(shù)沒有區(qū)別,使用方法上除了靜態(tài)成員函數(shù)在引用時要在前面加域作用符className::外,沒有其它任何區(qū)別,事實上全局函數(shù)也有可能放入命名空間,或者使用全局域作用符,例如 nameSpace::function() 或::function,這樣不僅本質(zhì)上相同,形勢上也與靜態(tài)成員函數(shù)一致了,所以它們是沒有區(qū)別的,放到一起討論。

這種情況比較簡單,只需要定義一個類型

#include <iostream>

#include <iomanip>

#include <tr1/memory>

#include <tr1/functional>

typedef ? std::tr1::function<void (int)> ??HandlerEvent;

然后再定義一個成員變量

class Sharp{

public:

?? ?HandlerEvent handlerEvent;

};

然后在其它函數(shù)內(nèi)就可以通過設置handlerEvent的值來動態(tài)裝載事件響應函數(shù)了,如:

class Rectangle{

private:

?? ?std::string name;

?? ?Sharp sharp;

public:

?? ?void initial(void);

?? ?const Sharp getSharp() const;

?? ?static void onEvent(int param){ ?//---------------(1)

?? ? ? ?std::cout << "invode onEvent method,get parameter: " << param << std::endl;

?? ?}

};

//類的實現(xiàn)方法

void Rectangle::initial(){

?? ?sharp.handlerEvent = HandlerEvent(&Rectangle::onEvent); //---------------(2)

?? ?std::cout << "invode initial function!" << std::endl;

}

const Sharp Rectangle::getSharp() const{

?? ?return sharp;

}

//下面為測試函數(shù):

int main(int argc,char *argv[]){

?? ?std::cout <<"hi: " << std::setw(50) << "hello world!" << std::endl;

?? ?Rectangle rectangle;

?? ?rectangle.initial(); ?//---------------(3)

?? ?rectangle.getSharp().handlerEvent(23); ? ?//---------------(4)

}

//輸出結(jié)果如下:

hi: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? hello world!

invode initial function!

invode onEvent method,get parameter: 23 ? ?//---------------(5)

?

注意,這里使用了靜態(tài)成員函數(shù),如果把Rectangle前面的static去掉這段代碼不能工作,編譯都不能通過,因為靜態(tài)成員函數(shù)與非靜態(tài)成員函數(shù)的參數(shù)表不一樣,原型相同的非靜態(tài)函數(shù)比靜態(tài)成員函數(shù)多一個參數(shù),即第一個參數(shù)this指針,指向所屬的對象,任何非靜態(tài)成員函數(shù)的第一個參數(shù)都是this指針,所以如果把Rectangle前面的static去掉,其函數(shù)原型等效于下面的一個全局函數(shù):

void onEvent(Rectangle* this, int);

所以,這與HandlerEvent所聲明的函數(shù)類型不匹配,編譯將不能通過。而且,既然靜態(tài)成員函數(shù)沒有this指針,所以上面(3)處的調(diào)用使sharp對象中的handlerEvent使向了Rectangle的靜態(tài)方法onEvent(),這樣當通過(4)處這樣調(diào)用時就會自動執(zhí)行(1)處的靜態(tài)函數(shù)onEvent()。

二、std::tr1::bind()模板函數(shù)的使用

通過上面的std::tr1::function 可以對靜態(tài)成員函數(shù)進行綁定,但如果要對非靜態(tài)成員函數(shù)的綁定,需用到下機將要介紹的bind()模板函數(shù).

首先說bind的用法,其聲明如下所示:

?? ?bind(Function fn, T1 t1, T2 t2, …, TN tN);

其中fn為將被調(diào)用的函數(shù),t1…tN為函數(shù)的參數(shù)。如果不指明參數(shù),則可以使用占位符表示形參,點位符格式為

std::tr1::placehoders::_1, ?std::tr1::placehoders::_2, ?…, ?std::tr1::placehoders::_N

將上例中Rectangle::onEvent(int param)前的static去掉改為非靜態(tài)成員函數(shù),則進行動態(tài)綁定使得程序正常運行,將Rectangle::initial(void)的定義修改為:

void Rectangle::initial(){

?? ?sharp.handlerEvent = std::tr1::bind(&Rectangle::onEvent,this,std::tr1::placeholders::_1/*因onEvent函數(shù)需要一個參數(shù),所以用一占位符*/);

?? ?std::cout << "invode initial function!" << std::endl;

}

這樣,便動態(tài)裝載函數(shù)成功。其它測試數(shù)據(jù)都不用進行修改。測試結(jié)果于上一樣。

三、指向虛成員函數(shù)的使用

對于虛成員函數(shù)的情況與上面第2節(jié)所說相同,仍然可以實現(xiàn)慮函數(shù)的效果。如果定義類Square繼承自Rectangle,將Rectangle::OnEvent重載,定義一個新的Square::OnEvent,Rectangle::initialize中的函數(shù)不變,仍然使用Rectangle::OnEvent進進綁定,則調(diào)用成員object.onEvent()時,具體執(zhí)行Rectangle::OnEvent還是Square::OnEvent,看object所屬對象的靜態(tài)類型是Rectangle還是Square而定.

下面為簡單示例:

我們首先修改一個上面Rectangle的initial()方法,改為虛函數(shù)。如:

?virtual void onEvent(int param){

?? ? ? ?std::cout << "invode Rectangle's onEvent method,get parameter: " << param << std::endl;

?? ?}

然后我們再寫一個Square類來繼承Rectangle類。并重寫onEvent方法。如:

class Square : public Rectangle{

public:

void onEvent(int param){

?? ? ? ?std::cout << "invode Square's onEvent method,get parameter: " << param << std::endl;

?? ?}

};

測試代碼:

int main(int argc,char *argv[]){

?? ?Rectangle rectangle;

?? ?rectangle.initial();

?? ?rectangle.getSharp().handlerEvent(23);

?? ?Square square;

?? ?square.initial();

?? ?square.getSharp().handlerEvent(33);

}

運行后的結(jié)果如下:

hi: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? hello world!

invode initial function!

invode Rectangle's onEvent method,get parameter: 23

invode initial function!

invode Square's onEvent method,get parameter: 33

這樣我們就可以看到sharp會針對具體對象來調(diào)用相應的onEvent()方法。 上面的程序示例讀者可自行研習。

總結(jié)

以上是生活随笔為你收集整理的C++中std::tr1::function和bind 组件的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。