c++ Boost库之boost::bind学习
剛開(kāi)始學(xué)c++,就看boost庫(kù)其實(shí)有點(diǎn)小小的不情愿。
團(tuán)隊(duì)要求必掌握的Boost庫(kù):
boost::bind
boost::function
boost::Signals2
學(xué)習(xí)前奏:在寫(xiě)關(guān)于cocos2d-x的helloworld例子時(shí),一直搞不明白這句代碼的意思(以前搞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) );最近知道原來(lái)方法也是可以做為一種類(lèi)型傳其它函數(shù)。把參數(shù)定義為類(lèi)型
繞了半天做了個(gè)行似的。為什么在cocos2d-x要這樣做呢?抽象時(shí),引擎制作者并不知道每一幀動(dòng)畫(huà),或沒(méi)隔x時(shí)間,執(zhí)行一下你的UpdateGame()方法,由于你起名字不一定起UpdateGame()而且不一定有幾個(gè)那樣的方法(可以重寫(xiě)一下UpdateGame()使他執(zhí)行你想關(guān)聯(lián)的方法,但是執(zhí)行的時(shí)間也不一定相同所以操作復(fù)雜度大大增加),所以直接定義成方法類(lèi)型。
從boost::bind開(kāi)始學(xué)習(xí)Boost庫(kù):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是標(biāo)準(zhǔn)方法std::bind1st&std::bind2nd的一般化。它支持任意的方法對(duì)象s,方法s,方法s的指針,和成員方法指針s,它可以給任何參數(shù)綁定一個(gè)指定的值,或者發(fā)送參數(shù)放到任何位置。比較痛苦的事,現(xiàn)在我還沒(méi)看過(guò),std::bind1st&std::bind2nd。我感覺(jué)自己有點(diǎn)誤入歧途了,雖然剛剛掌握函數(shù)類(lèi)型,但這肯定不是問(wèn)題的關(guān)鍵。
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 }
一個(gè)用bind1st一個(gè)不用,都能得到相同的結(jié)果,難道是第一個(gè)在類(lèi)體中的原因?先看一下bind1st和bind2nd的概念:它們是類(lèi)庫(kù)模版,他們有個(gè)有趣的特征,能將某個(gè)值綁定到一個(gè)二元函數(shù)對(duì)象的一個(gè)參數(shù)之上,例如:
有函數(shù)T f(x, y);bind1st(f, x1)將生成一個(gè)與f(x, y) 類(lèi)型一致的函數(shù)對(duì)象F;這里x1是一個(gè)給定值,綁定到函數(shù)f的x上。
有函數(shù)T f(x, y);bind2nd(f, y1)將生成一個(gè)與f(x, y) 類(lèi)型一致的函數(shù)對(duì)象F;同理。
?stl的for_each還不太會(huì)弄,先屏蔽掉,專(zhuān)心弄清楚bind1st&bind2st上面的bind1st看起來(lái)有點(diǎn)復(fù)雜,綁定的是成員函數(shù)了,還是看一下msdn文檔吧
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.
先不仔細(xì)研究bind1st&bind2nd等了,大概就是把二元函數(shù)改變成一元函數(shù)符合自己編程的需求。返回值是一個(gè) function object,到bind中的function object再追究以前了解的function object的一些問(wèn)題;最后再把總體知識(shí)總結(jié)起來(lái),現(xiàn)在很多認(rèn)識(shí)都是錯(cuò)的。
boost::bind開(kāi)始,先下載boost庫(kù),下載的時(shí)間來(lái)了解一下什么是function obejct:Function object 是一個(gè)對(duì)象,不過(guò)它的行為表現(xiàn)的像函數(shù)。一般而言,它是由一個(gè)重載了operator()的類(lèi)所實(shí)例化得來(lái)的對(duì)象。Function object的涵義比通常意義上的函數(shù)更廣泛,以為它可以在多次調(diào)用之間保持某種“狀態(tài)”——這和靜態(tài)局部變量有異曲同工之妙;不過(guò)這種“狀態(tài)”還可以被初始化,還可以從外面來(lái)檢測(cè),這可要比靜態(tài)局部變量強(qiáng)了。
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)一般情況下,產(chǎn)生的方法對(duì)象的operator()的類(lèi)型必須特別的指明。
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 // 這個(gè)暫時(shí)不仔細(xì)研究
?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本以為很麻煩,結(jié)果在boost壓縮包中index.html中介紹說(shuō)“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” 好了,把源碼都在頭文件中,只需把頭文件目錄包含到項(xiàng)目中就可以了。
筆記完成,看書(shū)我比較喜歡抄書(shū),這樣印象深刻,當(dāng)時(shí)考會(huì)計(jì)時(shí),幾乎把會(huì)計(jì)基礎(chǔ)、財(cái)會(huì)和審計(jì)整本書(shū)抄了一遍,比單純的看效果好多了。
回過(guò)頭來(lái)看,我已經(jīng)不知道我都看了哪些東西,哪些東西當(dāng)時(shí)思考的有問(wèn)題,但是自己對(duì)幾個(gè)概念的了解加深了:
1.函數(shù)類(lèi)型——typedef 定義作用,說(shuō)白了傳函數(shù)就是傳指針,不過(guò)對(duì)于c++這中強(qiáng)制類(lèi)型檢查的語(yǔ)言不得不給編譯器一個(gè)模版來(lái)識(shí)別這種類(lèi)型(這句話(huà)有沒(méi)有問(wèn)題?以后再想想),這是以前java中所沒(méi)有的;
2.object functions 對(duì)象函數(shù),就是一種特殊的class(stuct)重載操作符operator(),bind的時(shí)候通過(guò)返回值類(lèi)型參數(shù)個(gè)數(shù)和類(lèi)型來(lái)確定是哪個(gè)operator()。這樣用起來(lái)和用bind方法看起來(lái)十分相似。
3.綁定成員函數(shù),成員函數(shù)函數(shù)名不是它的指針,(&X::f)這樣寫(xiě)才行,引出bind(&X::f, args) == bind<R>(men_fn(&X::f),args)。這樣第三處代碼funtest中bind1st(mem_fun(&funtest::doSth),this)也就可以猜出什么意思了,把this綁定到doSth的最左的變量上(成員變量this原本是默認(rèn)綁定上的)。
最后stl中的for_each也明白了for_each(str.begin(), str.end(), bind1st(mem_fun(&funtest::doSth),this));把str中的每個(gè)元素作為參數(shù)送到第三個(gè)參數(shù)(是個(gè)函數(shù)的指針)所指向的函數(shù)。
boost::function
先把看bind文檔時(shí)最后一個(gè)關(guān)于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 }我現(xiàn)在可以通過(guò)boost::bind()的返回值,做一個(gè)猜想,boost::function<void()> onClick;是一個(gè)函數(shù)類(lèi)型的指針,指向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庫(kù)包含一系列是包裹函數(shù)對(duì)象類(lèi)的模版。這個(gè)概念很像通用的一個(gè)回調(diào)。它與函數(shù)指針(都定義了一個(gè)調(diào)用接口通過(guò)實(shí)現(xiàn)就可以被調(diào)用)來(lái)共用表現(xiàn)(features 啥東西呢 應(yīng)該指函數(shù)吧),通過(guò)這個(gè)程序?qū)崿F(xiàn)就可以被變化的調(diào)用。一般來(lái)說(shuō),在函數(shù)指針被調(diào)用或回調(diào),Boost.Function會(huì)被替代來(lái)允許用戶(hù)更加靈活在目標(biāo)的實(shí)現(xiàn)上。目標(biāo)可以是任何兼容的對(duì)象函數(shù)(或函數(shù)指針),意味著用Boost.Function類(lèi)型接口參數(shù)可以被轉(zhuǎn)換為目標(biāo)對(duì)象函數(shù)的參數(shù)。——翻譯的太差 理解了后再改下
大膽猜測(cè)一下,boost::function綁定類(lèi)似多態(tài)機(jī)制(virtual函數(shù)的動(dòng)態(tài)綁定)。
總結(jié)
以上是生活随笔為你收集整理的c++ Boost库之boost::bind学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: boost::bind 介绍
- 下一篇: Linux内存管理之mmap详解