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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

boost::function的用法(二)

發(fā)布時(shí)間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 boost::function的用法(二) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

boost function是一組類和模板組合,用于包裝各種函數(shù)。從功能上,它類似于函數(shù)指針,但是比函數(shù)指針的功能更強(qiáng)大。

使用boost function,必須包含頭文件

[cpp]?view plaincopy
  • #include?<boost/function.hpp>??

  • 除了頭文件外,不需要額外的庫(kù)。

    注意,boost function有兩種形式:一種為推薦形式;另外一種為可移植形式。推薦形式的語(yǔ)法更加簡(jiǎn)潔;可移植形式的可移植性好,但是語(yǔ)法羅嗦。由于目前的gcc/vc的版本都已經(jīng)能夠使用推薦形式了,因此,可移植形式就不在描述。有興趣的可以參閱boost相關(guān)文檔。

    boost function 基本用法

    例如,有一個(gè)函數(shù)

    [cpp]?view plaincopy
  • float?int_div(int?x,?int?y)??
  • {??
  • ????return?((float)x)/y;??
  • }??

  • 我們可以這樣使用

    [cpp]?view plaincopy
  • boost::function<float?(int?x,?int?y)>?f;??
  • f?=?int_div;??
  • std::cout<<?f(5,3)?<<?std::endl;??

  • 可以看到,它的用法和函數(shù)指針很相似的。

    當(dāng)然,boost::function不止這些,請(qǐng)看下面的函數(shù)對(duì)象:

    [cpp]?view plaincopy
  • struct?int_add?{??
  • ????float?operator()(int?x,?int?y)?{??
  • ????????return?(float)(x?+?y);??
  • ????}??
  • };??

  • 上面的 boost::function<float (int x, int y)> f 聲明的f對(duì)象,仍舊可以保存int_add:

    [cpp]?view plaincopy
  • f?=?int_add();??
  • std::cout?<<?"f?add?:?"<<?f(10,20)?<<?std::endl;??

  • 另外,boost::function還可以用來(lái)判斷函數(shù)是否為空

    [cpp]?view plaincopy
  • if(f)??
  • ????std::cout??<<?"?f?is?ok!"<<?std::endl;??

  • 要清空f(shuō),可以使用

    [cpp]?view plaincopy
  • f?=?0;??
  • if(!f)??
  • ????std::cout?<<?"f?is?cleard!"?<<?std::endl;??

  • 針對(duì)成員函數(shù)

    成員函數(shù),也可以被綁定,如有類 [cpp]?view plaincopy
  • struct?X?{??
  • ????int?foo(int?x)?{??
  • ????????std::cout?<<?"X?"?<<?this?<<?"?foo?x="<<x?<<?std::endl;??
  • ????????return?x?+?100;??
  • ????};??
  • };??

  • 可以這樣使用 [cpp]?view plaincopy
  • boost::function<int?(X*,?int)>?mf;??
  • mf?=?&X::foo;??
  • ??
  • X?x;??
  • mf(&x,?5);??

  • 和bind同時(shí)使用

    在需要包裝參數(shù)的場(chǎng)合,我們可以配合boost::bind一起使用。 首先,加入boost::bind的頭文件 [cpp]?view plaincopy
  • #include?<boost/bind.hpp>??
  • 這樣使用 [cpp]?view plaincopy
  • boost::function<int?(int)>?mbf;??
  • mbf?=?bind(&X::foo,?&x,?_1);??
  • mbf(10);??

  • bind將x的指針保存在function對(duì)象中。


    function factory

    function factory是一個(gè)封裝類工廠的模板。它有兩種,一種是value_factory,一種是factory。
    [cpp]?view plaincopy
  • boost::factory<T*>()(arg1,arg2,arg3)???
  • //?same?as?new?T(arg1,arg2,arg3)??
  • ??
  • boost::value_factory<T>()(arg1,arg2,arg3)??
  • //?same?as?T(arg1,arg2,arg3)??

  • 使用function factory的原因

    我們考慮這樣的場(chǎng)景:使用抽象工廠模式,有一個(gè)接口,有若干個(gè)實(shí)現(xiàn),通常的做法是這樣的: [cpp]?view plaincopy
  • //聲明接口??
  • class?Interface???
  • {??
  • public:??
  • ???virtual?void?print(int?a)?=?0;?//接口函數(shù)??
  • };??
  • //聲明抽象工廠??
  • class?Interface_Factory?{??
  • public:??
  • ????virtual?Interface?*?create()?=?0;??
  • };??

  • 然后,我們有若干個(gè)實(shí)現(xiàn) [cpp]?view plaincopy
  • class?ImplA?:?public?Interface??
  • {??
  • public:??
  • ???virtual?void?print(int?a)?{??
  • ??????std::cout?<<?"==?A?==??a="?<<?a?<<?std::endl;??
  • ???}??
  • };??
  • //提供ImplA的類工廠??
  • class?ImplA_Factory?:?public?Interface_Factory??
  • {??
  • public:??
  • ????Interface?*?create()?{?return?new?ImplA();?}??
  • ????static?ImplA_Factory?_implAFactory;??
  • };??
  • ImplA_Factory?ImplA_Factory::_implAFactory;??
  • ??
  • //同理,ImplB的實(shí)現(xiàn)??
  • ??
  • class?ImplB?:?public?Interface??
  • {??
  • public:??
  • ???virtual?void?print(int?a)?{??
  • ??????std::cout?<<?"==?B?==??a="?<<?a?<<?std::endl;??
  • ???}??
  • };??
  • //提供ImplB的類工廠??
  • class?ImplB_Factory?:?public?Interface_Factory??
  • {??
  • public:??
  • ????Interface?*?create()?{?return?new?ImplB();?}??
  • ????static?ImplB_Factory?_implBFactory;??
  • };??
  • ImplB_Factory?ImplB_Factory::_implBFactory;??
  • 如果你要使用它,就需要這些寫 [cpp]?view plaincopy
  • std::map<std::string,?Interface_Factory*>?factories;??
  • ??
  • int?main()??
  • {??
  • ????factories["A"]?=?&ImplA_Factory::_implAFactory;??
  • ????factories["B"]?=?&ImplB_Factory::_implBFactory;??
  • .....??
  • }??

  • 如果仔細(xì)觀察下,就會(huì)發(fā)現(xiàn),實(shí)際上,ImplA_Factory和ImplB_Factory的內(nèi)容幾乎都一樣。但是卻寫了不少重復(fù)性的代碼。factory就是解決該問(wèn)題的。

    factory的解決之道

    使用boost::factory,是完全不需要定義Interface_Factory接口和對(duì)應(yīng)的實(shí)現(xiàn)的,我們定義一個(gè)boost::function對(duì)象,替代Interface_Factory [cpp]?view plaincopy
  • typedef?boost::function<?I?*()?>?I_factory;?//替代Interface_Factory的定義??
  • 用boost::factory替代ImplA_Factory和ImplB_Factory: [cpp]?view plaincopy
  • std::map<std::string,?I_factory>?factories;??
  • ....??
  • ??
  • ????factories["A"]?=?boost::factory<ImplA*>?();??//等價(jià)于?&ImplA_Factory::_ImplAFactory;??
  • ????factories["B"]?=?boost::factory<ImplB*>?();?//等價(jià)于?&ImplB_Factory::_ImplBFactory;??

  • 在使用的時(shí)候,與普通方法絲毫不差,如 [cpp]?view plaincopy
  • void?run_interface(const?char*?name)??
  • {??
  • ????I_factory?factory?=?factories[name];??
  • ????if(!factory)??
  • ????{?????
  • ????????std::cout<<"factory?"?<<?name?<<?"?is?not?exist"?<<?std::endl;??
  • ????????return;??
  • ????}?????
  • ????I?*i?=?factory();??
  • ????i->print(100);??
  • ????delete?i;??
  • }??
  • 通過(guò)判斷factory的函數(shù)是否為空,就可以知道對(duì)應(yīng)的類實(shí)現(xiàn)是否存在。我們可以這樣簡(jiǎn)單的使用 [cpp]?view plaincopy
  • run_interface("A");??
  • run_interface("B");??
  • run_interface("C");??
  • 由于"C"對(duì)象不存在,因此,將打印 "factory C is not exist"的信息。

    OverloadedFunction

    考慮下面的代碼 [cpp]?view plaincopy
  • const?std::string&?identity_s(const?std::string&?x)?//?Function?(as?pointer).??
  • ????{?return?x;?}??
  • ??
  • int?identity_i_impl(int?x)?{?return?x;?}??
  • int?(&identity_i)(int)?=?identity_i_impl;?//?Function?reference.??
  • ??
  • double?identity_d_impl(double?x)?{?return?x;?}??
  • boost::function<double?(double)>?identity_d?=?identity_d_impl;?//?Functor.??

  • 在調(diào)用他們的時(shí)候,必須使用各自的函數(shù)名:identity_i, indentity_s, indentity_d; 例如 [cpp]?view plaincopy
  • BOOST_TEST(identity_s("abc")?==?"abc");??
  • BOOST_TEST(identity_i(123)?==?123);??
  • BOOST_TEST(identity_d(1.23)?==?1.23);??

  • 但是,使用OverlaodedFunction,就可以使用統(tǒng)一的名字identity來(lái)調(diào)用了: [cpp]?view plaincopy
  • boost::overloaded_function<??
  • ??????const?std::string&?(const?std::string&)??
  • ????,?int?(int)??
  • ????,?double?(double)??
  • >?identity(identity_s,?identity_i,?identity_d);??
  • ??
  • //?All?calls?via?single?`identity`?function.??
  • BOOST_TEST(identity("abc")?==?"abc");??
  • BOOST_TEST(identity(123)?==?123);??
  • BOOST_TEST(identity(1.23)?==?1.23);??
  • 總結(jié)

    以上是生活随笔為你收集整理的boost::function的用法(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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