• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            ACG狂人

            其實我更愛姐汁...

            boost::bind綁定成員函數時,第一個參數傳遞對象的特殊情況

            boost::bind(&memberfunction, obj, _1, _2........)類似這樣的用法,我們叫做成員函數綁定,boost庫的文檔中說的很清楚,第一個參數可以是value、pointer和reference,即傳值、傳地址和傳引用都是可以的,所以在一般情況下,下面三種使用bind的形式都是成立的。

            class A
            {
            public:
                
            void func();
            }
            ;


            A a;
            A
            & r = a;

            boost::bind(
            &A::func, a);
            boost::bind(
            &a::func, &a);
            boost::bind(
            &a::func, r);

            由上面的代碼可以看出,我們可以隨便傳任意一種類對象的形式,函數模板會自動尋找最為匹配的為我們實現。但是有兩種情況是特殊的,即:
            1、該對象不可進行拷貝構造函數。
            2、該對象不可隨意被析構。
            發現這個問題是在我編寫單件模式時的遇見的,當時發現我的單件對象在bind中被析構了一次,這很不尋常,為什么bind會調用第一個參數的析構呢?跟蹤進了boost的源碼才發現,原來所有的參數都會被拷貝一遍,然后析構一遍,這樣一來,我們傳遞參數的時候就會有一些小麻煩了,首先必須保證參數能夠被拷貝而不影響邏輯和數據一致性,其次,參數能夠被析構而不影響邏輯和數據一致性。單件是全局性質的數據,所以絕對不可以析構,那么這種情況的話,我們只好傳遞單件對象的地址,而不能傳遞值或引用。

            另:附上出錯問題的代碼如下
            class InputDevice
                : 
            public EventSource
                , 
            public Singleton<InputDevice>
            {
            public:
                
            }
            ;

            class TestUI
                : 
            public Singleton<TestUI>
            {
            public:
                
            ~TestUI(){
                    std::cout
            <<"~TestUI"<<std::endl;
                }

                
            void processKeyboard(EventArgs& args){
                    std::cout
            <<"鍵盤響應"<<std::endl;
                }


                
            void processMouse(EventArgs& args){
                    std::cout
            <<"鼠標響應"<<std::endl;
                }

            }
            ;


            int _tmain(int argc, _TCHAR* argv[])
            {
                
            new FrameUpdaterManager;
                
            new DelayEventSender;
                
            new InputDevice;
                
            new TestUI;

                InputDevice::getSingleton().mEventSet.addEvent(
            "KeyDown", Event());
                InputDevice::getSingleton().mEventSet.addEvent(
            "KeyUp", Event());
                InputDevice::getSingleton().mEventSet.addEvent(
            "MouseLDown", Event());
                InputDevice::getSingleton().mEventSet.addEvent(
            "MouseLUp", Event());
                InputDevice::getSingleton().mEventSet.addEvent(
            "MouseRDown", Event());
                InputDevice::getSingleton().mEventSet.addEvent(
            "MouseRUp", Event());


                
            //TestUI& ui = TestUI::getSingleton(); // 用此行便會出錯
                TestUI* ui = TestUI::getSingletonPtr();

                
            // 出錯開始
                InputDevice::getSingleton().mEventSet["KeyDown"+= boost::bind(&TestUI::processKeyboard, ui, _1);
                InputDevice::getSingleton().mEventSet[
            "KeyUp"+= boost::bind(&TestUI::processKeyboard, ui, _1);

                InputDevice::getSingleton().mEventSet[
            "MouseLDown"+= boost::bind(&TestUI::processMouse, ui, _1);
                InputDevice::getSingleton().mEventSet[
            "MouseLUp"+= boost::bind(&TestUI::processMouse, ui, _1);
                InputDevice::getSingleton().mEventSet[
            "MouseRDown"+= boost::bind(&TestUI::processMouse, ui, _1);
                InputDevice::getSingleton().mEventSet[
            "MouseRUp"+= boost::bind(&TestUI::processMouse, ui, _1);


                delete TestUI::getSingletonPtr();
                delete InputDevice::getSingletonPtr();
                delete DelayEventSender::getSingletonPtr();
                delete FrameUpdaterManager::getSingletonPtr();
                
            return 0;
            }

            posted on 2009-06-15 22:34 釀妹汁 閱讀(5784) 評論(4)  編輯 收藏 引用 所屬分類: C++

            評論

            # re: boost::bind綁定成員函數時,第一個參數傳遞對象的特殊情況 2009-06-16 00:14 一個無聊的人

            為啥不用boost::mem_fn ?  回復  更多評論   

            # re: boost::bind綁定成員函數時,第一個參數傳遞對象的特殊情況 2009-06-16 08:27 董波

            6.2. Requirements for Call Wrapper Types
            TR1 defines some additional terms that are used to describe requirements for callable types.

            First, INVOKE(fn, t1, t2, ..., tN) describes the effect of calling a callable object fn with the arguments t1, t2, ..., tN. Naturally, the effect depends on the type of the callable object. INVOKE is defined as follows:

            (t1.*fn)(t2, ..., tN) when fn is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T

            ((*t1).*fn)(t2, ..., tN) when fn is a pointer to a member function of a class T and t1 is not one of the types described in the previous item

            t1.*fn when fn is a pointer to member data of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T

            (*t1).*fn when fn is a pointer to member data of a class T and t1 is not one of the types described in the previous item

            fn(t1, t2, ..., tN) in all other cases

            What this amounts to is that when the callable object is an ordinary function or a pointer to an ordinary function, INVOKE means to call that function, passing the rest of the arguments to the function call. When the callable object is a pointer to member, the next argument refers to the object that it should be applied to. That argument is the object itself, a reference to the object, a pointer to the object, or some kind of smart pointer that points to the object. The rest of the arguments are passed to the function call.

            Second, INVOKE_R(fn, t1, t2, ..., tN, Ret) describes the effect of calling a callable object fn with an explicit return type, Ret. It is defined as INVOKE(fn, t1, t2, ..., tN) implicitly converted to Ret.[5]

            [5] In the TR, this metafunction is named INVOKE; although I'm one of the people responsible for this name overloading, I've now concluded that it's too clever and shouldn't be used.

            Third, some call wrapper types have a weak result type; this means that they have a nested member named result_type that names a type determined from the call wrapper's target type, Ty.

            If Ty is a function, reference to function, pointer to function, or pointer to member function, result_type is a synonym for the return type of Ty

            If Ty is a class type with a member type named result_type, result_type is a synonym for Ty::result_type

            Otherwise, result_type is not defined[6]

            [6] That is, not defined as a consequence of having a weak result type. Some call wrapper types have a weak result type in certain circumstances, have a specific type named result_type

            A few examples will help clarify what this rather dense text means:

            struct base {
            void f();
            int g(double);
            int h(double,double);
            };
            struct derived : base {
            };

            base b;
            derived d;
            base& br = d;



            With these definitions, rule 1 gives the following meanings to these uses of INVOKE .

            Phrase
            Meaning

            INVOKE (&base::f, b)
            (b.*f)()

            INVOKE (&base::g, d, 1.0)
            (d.*f)(1.0)

            INVOKE (&base::h, br, 1.0, 2.0)
            (br.*f)(1.0, 2.0)





            That is, the pointer to member function is called on the object or reference named by t1:

            derived *dp = new derived;
            base *bp = dp;
            shared_ptr<base> sp(bp);



            With these additional definitions, rule 2 gives the following meanings to these uses of ( INVOKE):

            Phrase
            Meaning

            INVOKE (&base::f, bp)
            ((*bp).*f)()

            INVOKE (&base::g, dp, 1.0)
            ((*dp).*f)(1.0)

            INVOKE (&base::h, sp, 1.0, 2.0)
            ((*sp).*f)(1.0, 2.0)





            That is, the pointer to member function is called on the object that the argument t1 points to. Since it uniformly dereferences that argument, the rule works for any type whose operator* returns a reference to a suitable object. In particular, the rule works for shared_ptr objects.

            Rules 3 and 4 give similar meanings to INVOKE uses that apply pointers to member data:

            void func(base&);
            struct fun_obj {
            void operator()() const;
            bool operator()(int) const;
            };
            fun_obj obj;



            With these additional definitions, rule 5 gives the following meanings to these uses of INVOKE:

            Phrase
            Meaning

            INVOKE (func, d)
            func(d)

            INVOKE (obj)
            obj()

            INVOKE (obj, 3)
            obj(3)


              回復  更多評論   

            # re: boost::bind綁定成員函數時,第一個參數傳遞對象的特殊情況 2009-06-16 23:25 wp

            文檔上有說明  回復  更多評論   

            # re: boost::bind綁定成員函數時,第一個參數傳遞對象的特殊情況 2009-06-19 14:49

            哎!我沒耐心看完文檔,有點操之過急了,呵呵,得接受這個教訓  回復  更多評論   

            久久婷婷成人综合色综合| avtt天堂网久久精品| 国产999精品久久久久久| 久久e热在这里只有国产中文精品99| 久久精品国产一区| 天天影视色香欲综合久久| 久久久不卡国产精品一区二区| 亚洲国产一成久久精品国产成人综合 | 久久免费观看视频| 97久久精品人人澡人人爽| 久久久久久久综合日本| 99久久夜色精品国产网站| 精品国产91久久久久久久| 亚洲?V乱码久久精品蜜桃| 国产精品一久久香蕉国产线看观看| 狠狠色伊人久久精品综合网| 少妇久久久久久被弄到高潮| 亚洲狠狠婷婷综合久久蜜芽| 尹人香蕉久久99天天拍| 麻豆一区二区99久久久久| 国产亚州精品女人久久久久久 | 久久青青草原亚洲av无码app| 欧美一区二区精品久久| 亚洲国产欧洲综合997久久| 久久国产三级无码一区二区| 精品久久久久久无码专区不卡| 久久久久国产精品三级网| 99久久99这里只有免费的精品| 久久精品综合网| 伊人久久亚洲综合影院| 久久久久国产精品三级网| 久久国产午夜精品一区二区三区| av午夜福利一片免费看久久| 日韩人妻无码精品久久久不卡| 亚洲精品国精品久久99热| 久久高潮一级毛片免费| 精品熟女少妇a∨免费久久| 久久午夜福利电影| 久久亚洲国产精品五月天婷| 久久久久无码中| 午夜精品久久久久9999高清|