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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

c++ Boost库之boost::bind学习

發布時間:2025/3/21 c/c++ 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ Boost库之boost::bind学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


  剛開始學c++,就看boost庫其實有點小小的不情愿。
團隊要求必掌握的Boost庫:
boost::bind
boost::function
boost::Signals2

  學習前奏:在寫關于cocos2d-x的helloworld例子時,一直搞不明白這句代碼的意思(以前搞java的)

1 void UpdateGame(cocos2d::ccTime time); 2 void CollideDetect(cocos2d::ccTime time); 3 4 this->schedule( schedule_selector(HelloWorld::UpdateGame), 0.05f ); 5 this->schedule( schedule_selector(HelloWorld::CollideDetect) );

最近知道原來方法也是可以做為一種類型傳其它函數。把參數定義為類型

1 typedef void (*FUN_TYPE) (int); 2 3 #define schedule_selector FUN_TYPE 4 5 void schedule( FUN_TYPE f, int i) { 6 f(i); 7 } 8 9 10 void UpdateGame(int i) { 11 printf("hello %d", i); 12 } 13 14 15 int _tmain(int argc, _TCHAR* argv[]) 16 { 17 schedule( schedule_selector(UpdateGame), 1); 18 return 0; 19 }

繞了半天做了個行似的。為什么在cocos2d-x要這樣做呢?抽象時,引擎制作者并不知道每一幀動畫,或沒隔x時間,執行一下你的UpdateGame()方法,由于你起名字不一定起UpdateGame()而且不一定有幾個那樣的方法(可以重寫一下UpdateGame()使他執行你想關聯的方法,但是執行的時間也不一定相同所以操作復雜度大大增加),所以直接定義成方法類型。

  從boost::bind開始學習Boost庫:boost::bind is a generalization of the standard functions std::bind1st and std::bind2nd. It supports arbitrary function objects, functions, function pointers, and member function pointers, and is able to bind any argument to a specific value or route input arguments into arbitrary positions.譯:boost::bind是標準方法std::bind1st&std::bind2nd的一般化。它支持任意的方法對象s,方法s,方法s的指針,和成員方法指針s,它可以給任何參數綁定一個指定的值,或者發送參數放到任何位置。比較痛苦的事,現在我還沒看過,std::bind1st&std::bind2nd。我感覺自己有點誤入歧途了,雖然剛剛掌握函數類型,但這肯定不是問題的關鍵。

1 class funtest { 2 public: 3 string str; 4 public: 5 void doSth(char c) { 6 cout << "char: " << c << endl; 7 } 8 9 void test() { 10 for_each(str.begin(), str.end(), bind1st(mem_fun(&funtest::doSth),this)); 11 } 12 }; 13 14 int main(int argc, char* argv[]) 15 { 16 funtest test; 17 test.str = "ABCDEFG"; 18 test.test(); 19 return 0; 20 }


void doSth(char c) {cout << "char: " << c << endl; }int main(int argc, char* argv[]) {string str = "abc";for_each(str.begin(), str.end(), doSth);return 0; }

一個用bind1st一個不用,都能得到相同的結果,難道是第一個在類體中的原因?先看一下bind1st和bind2nd的概念:它們是類庫模版,他們有個有趣的特征,能將某個值綁定到一個二元函數對象的一個參數之上,例如:
有函數T f(x, y);bind1st(f, x1)將生成一個與f(x, y) 類型一致的函數對象F;這里x1是一個給定值,綁定到函數f的x上。
有函數T f(x, y);bind2nd(f, y1)將生成一個與f(x, y) 類型一致的函數對象F;同理。
?stl的for_each還不太會弄,先屏蔽掉,專心弄清楚bind1st&bind2st上面的bind1st看起來有點復雜,綁定的是成員函數了,還是看一下msdn文檔吧

1 template<class Operation, class Type> 2 binder1st <Operation> bind1st( 3 const Operation& _Func, 4 const Type& _Left 5 );

Function binders are a kind of function adaptor and,because they return function objects,can be used in cetain types of function composition to construct more complicated and powerful expressions.if _Func is an object of type Operation and c is a constant,then bind1st(_Func, c )is equivalent to the binder1st constructor binder1st<Operation>(_Func, c )and is more convenient.
先不仔細研究bind1st&bind2nd等了,大概就是把二元函數改變成一元函數符合自己編程的需求。返回值是一個 function object,到bind中的function object再追究以前了解的function object的一些問題;最后再把總體知識總結起來,現在很多認識都是錯的。
  

  boost::bind開始,先下載boost庫,下載的時間來了解一下什么是function obejct:Function object 是一個對象,不過它的行為表現的像函數。一般而言,它是由一個重載了operator()的類所實例化得來的對象。Function object的涵義比通常意義上的函數更廣泛,以為它可以在多次調用之間保持某種“狀態”——這和靜態局部變量有異曲同工之妙;不過這種“狀態”還可以被初始化,還可以從外面來檢測,這可要比靜態局部變量強了。
  bind with functions and function pointers
  bing with function objects:In the gneral case, the return type of the generated function object's operator()has to be specified explicitly (without a typeof operator the return type cannot be inferred)一般情況下,產生的方法對象的operator()的類型必須特別的指明。

1 struct F 2 { 3 int operator()(int a, int b) { return a - b; } 4 bool operator()(long a, long b) { return a == b; } 5 }; 6 7 F f; 8 9 int x = 104; 10 11 bind<int>(f, _1, _1)(x); // f(x, x), i.e. zero

  Using bind with pointers to members
  pointers to member functions and pointers to data members are not function objects, because they do not support operator().for convenience, bind accepts member pointers as its first argument, and the behavior is as if boost::mem_fn has been used to convert the member pointer into a function object. In other words, the expression
bind(&X::f, args)  is equivalent to   bind<R>(men_fn(&X::f), args)
where R is the return type of X::f(for member functions) or the type of the member(for data members).?[Note:mem_fn creates function objects that are able to accept a pointer,a reference, or a smart pointer to an object as its first argument]
  Using nested binds for function compostion // 這個暫時不仔細研究
  ?Some of the arguments passed to bind may be nested bind expression themselves:
bind(f, bind(g,_1))(x);
the inner bind expressions are evaluated, in unspecified order, before the outer bind when the function object is called;the results of the evaluation are then substitued in their place when the outer bind is evaluated.In the exaple above, when the function object is called with the argument list(x),bind(g, _1)(x) is evaluated first, yielding g(x), and then bind(f, g(x))(x) is evaluated,yielding the final result f(g(x)).

  安裝Boost本以為很麻煩,結果在boost壓縮包中index.html中介紹說“most boost libraries are header_only:they consist entirely of header files containing templates and inline functions,and require no separately-compiled library binaries or special treatment when linking” 好了,把源碼都在頭文件中,只需把頭文件目錄包含到項目中就可以了。

  筆記完成,看書我比較喜歡抄書,這樣印象深刻,當時考會計時,幾乎把會計基礎、財會和審計整本書抄了一遍,比單純的看效果好多了。


  回過頭來看,我已經不知道我都看了哪些東西,哪些東西當時思考的有問題,但是自己對幾個概念的了解加深了:
1.函數類型——typedef 定義作用,說白了傳函數就是傳指針,不過對于c++這中強制類型檢查的語言不得不給編譯器一個模版來識別這種類型(這句話有沒有問題?以后再想想),這是以前java中所沒有的;
2.object functions 對象函數,就是一種特殊的class(stuct)重載操作符operator(),bind的時候通過返回值類型參數個數和類型來確定是哪個operator()。這樣用起來和用bind方法看起來十分相似。
3.綁定成員函數,成員函數函數名不是它的指針,(&X::f)這樣寫才行,引出bind(&X::f, args) == bind<R>(men_fn(&X::f),args)。這樣第三處代碼funtest中
bind1st(mem_fun(&funtest::doSth),this)也就可以猜出什么意思了,把this綁定到doSth的最左的變量上(成員變量this原本是默認綁定上的)。
最后stl中的for_each也明白了
for_each(str.begin(), str.end(), bind1st(mem_fun(&funtest::doSth),this));把str中的每個元素作為參數送到第三個參數(是個函數的指針)所指向的函數。

  boost::function
  

  先把看bind文檔時最后一個關于Function的例子貼上:

1 class button 2 { 3 public: 4 5 boost::function<void()> onClick; 6 }; 7 8 class player 9 { 10 public: 11 12 void play(); 13 void stop(); 14 }; 15 16 button playButton, stopButton; 17 player thePlayer; 18 19 void connect() 20 { 21 playButton.onClick = boost::bind(&player::play, &thePlayer); 22 stopButton.onClick = boost::bind(&player::stop, &thePlayer); 23 }

我現在可以通過boost::bind()的返回值,做一個猜想,boost::function<void()> onClick;是一個函數類型的指針,指向play()和stop(),this指針取thePlayer的地址。

  摘抄一下Introduction:The Boost.Function library contains a family of of class templates that are function object wrappers.The notion is similar to a generalized callback. It shares features with function pointers in that both define a call interface through which some implementation can be called, and the implementation that is invoked may change throughout the course of the program.
Generally, any place in which a function pointer would be used to defer a call or make a callback,Boost.Function can be used instead to allow the user greater flexibility in the implementation of the target. Targets can be any 'compatible' function object (or function pointer), meaning that the arguments to the interface designated by Boost.Function can be converted to the arguments of the target function object.//譯:boost.function庫包含一系列是包裹函數對象類的模版。這個概念很像通用的一個回調。它與函數指針(都定義了一個調用接口通過實現就可以被調用)來共用表現(features 啥東西呢 應該指函數吧),通過這個程序實現就可以被變化的調用。一般來說,在函數指針被調用或回調,Boost.Function會被替代來允許用戶更加靈活在目標的實現上。目標可以是任何兼容的對象函數(或函數指針),意味著用Boost.Function類型接口參數可以被轉換為目標對象函數的參數。——翻譯的太差 理解了后再改下

  大膽猜測一下,boost::function綁定類似多態機制(virtual函數的動態綁定)。

總結

以上是生活随笔為你收集整理的c++ Boost库之boost::bind学习的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。