青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

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 釀妹汁 閱讀(5840) 評論(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

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

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            一区二区三区四区国产| 久久爱另类一区二区小说| 欧美成人综合网站| 最新日韩在线视频| 亚洲高清免费在线| 欧美成年人视频| 夜夜嗨av一区二区三区网站四季av| 免费人成网站在线观看欧美高清| 久久综合九色欧美综合狠狠| 在线欧美一区| 亚洲欧洲视频在线| 欧美日韩精品伦理作品在线免费观看| 99国产精品久久久久久久久久| 亚洲日本aⅴ片在线观看香蕉| 欧美特黄a级高清免费大片a级| 亚洲欧美日本日韩| 久久大综合网| 日韩午夜电影| 午夜伦欧美伦电影理论片| 在线播放日韩欧美| 亚洲免费精品| 国产在线精品一区二区夜色| 欧美成人精品一区二区| 欧美日韩情趣电影| 久久久久9999亚洲精品| 欧美另类女人| 久久精品国产一区二区电影| 欧美激情精品久久久久| 欧美一区二区精美| 免费短视频成人日韩| 亚洲欧美清纯在线制服| 久久亚洲综合色一区二区三区| 一区二区日韩欧美| 久久精品国产一区二区电影| 一区二区三区欧美成人| 久久免费视频网站| 亚洲欧美日韩视频二区| 欧美福利视频网站| 久久野战av| 国产伦精品一区二区三区高清版 | 最新国产成人av网站网址麻豆 | 亚洲福利视频网站| 国产精品99一区| 亚洲国产精品免费| 影音先锋亚洲精品| 欧美一区二区三区四区在线观看地址 | 午夜一区二区三区在线观看| 亚洲精品美女在线| 久久精品国产久精国产一老狼| 亚洲视频电影在线| 欧美精品免费视频| 嫩草影视亚洲| 在线欧美三区| 久久久蜜桃精品| 久久频这里精品99香蕉| 国产精品久久久久久久久久妞妞| 亚洲东热激情| 亚洲日本va午夜在线影院| 欧美一区二区三区日韩| 香蕉成人啪国产精品视频综合网| 欧美日韩一二区| 亚洲欧洲一级| 亚洲美女免费精品视频在线观看| 久久免费黄色| 免费欧美在线视频| 在线电影欧美日韩一区二区私密| 久久精品成人一区二区三区| 欧美在线关看| 国产亚洲欧美色| 欧美在线一二三| 久久久亚洲国产天美传媒修理工| 国产欧美日韩一区| 亚洲欧美日韩一区二区| 欧美在线亚洲| 国内自拍视频一区二区三区| 欧美在线一二三四区| 久久久久久久久久久一区| 国产综合18久久久久久| 久久精品在线观看| 亚洲第一福利在线观看| 亚洲精品自在久久| 欧美极品欧美精品欧美视频| 最新日韩在线| 香蕉久久夜色精品| 激情视频一区二区三区| 牛人盗摄一区二区三区视频| 亚洲精品激情| 欧美一级淫片播放口| 国产午夜精品全部视频在线播放| 久久gogo国模裸体人体| 欧美黄色大片网站| 亚洲性图久久| 国产日韩精品视频一区| 久久在线免费观看视频| 亚洲毛片在线看| 欧美亚洲在线观看| 亚洲国产99精品国自产| 欧美日本一区二区视频在线观看| 亚洲一区二区成人在线观看| 久久久久国色av免费观看性色| 亚洲国产另类 国产精品国产免费| 欧美精品一卡| 久久精品人人做人人爽电影蜜月| 亚洲国产一区二区三区在线播 | 在线看国产日韩| 欧美欧美在线| 欧美专区在线观看一区| 亚洲精品社区| 久久中文字幕一区| 中日韩午夜理伦电影免费| 国产亚洲亚洲| 欧美视频在线一区二区三区| 欧美中文字幕在线观看| 亚洲精品一区二区在线| 久久久久久伊人| 亚洲一区二区三区高清| 亚洲电影免费观看高清完整版在线观看 | 国产日韩欧美亚洲一区| 欧美—级在线免费片| 久久精品国产一区二区三区| 国产精品99久久久久久有的能看| 欧美大片va欧美在线播放| 欧美一二三区精品| 一区二区三区精品视频在线观看| 国内免费精品永久在线视频| 国产精品久久久| 欧美激情第五页| 久久全球大尺度高清视频| 亚洲曰本av电影| 99亚洲一区二区| 亚洲欧洲在线一区| 免费影视亚洲| 美女成人午夜| 久久视频国产精品免费视频在线| 亚洲午夜女主播在线直播| 最新国产成人在线观看| 亚洲成人资源| 在线播放中文一区| 国内精品一区二区三区| 国产欧美精品在线| 国产精品日韩欧美一区| 欧美午夜精品久久久| 欧美精品一区二区三区在线看午夜 | 91久久精品日日躁夜夜躁欧美| 久久综合九色九九| 久久九九免费视频| 久久精品人人| 久久久久久久网| 久久欧美肥婆一二区| 玖玖国产精品视频| 另类亚洲自拍| 欧美大片免费观看在线观看网站推荐| 久久久福利视频| 玖玖国产精品视频| 欧美激情aaaa| 亚洲乱码国产乱码精品精| 日韩视频国产视频| 一区二区三区欧美成人| 亚洲一区日韩在线| 欧美一区二区三区在线| 久久久久久有精品国产| 嫩草影视亚洲| 欧美日韩中国免费专区在线看| 欧美区一区二| 国产精品视频第一区| 国产亚洲精品自拍| 亚洲高清久久久| 一本色道久久综合狠狠躁的推荐| 亚洲一区二区三区四区中文| 欧美一级播放| 欧美高清视频| 亚洲午夜久久久| 久久综合一区二区| 国产精品成人在线观看| 国产欧美一区在线| 亚洲黄色一区| 午夜精品久久久久久久99水蜜桃 | 午夜精品免费在线| 久久久久久久久伊人| 欧美伦理91| 国产人久久人人人人爽| 亚洲激情电影在线| 亚洲欧美电影院| 欧美成人免费网| 亚洲调教视频在线观看| 久久久.com| 国产精品久久久久久久久果冻传媒| 国内精品视频在线播放| 一级日韩一区在线观看| 久久免费视频这里只有精品| 亚洲欧洲一区二区三区在线观看| 欧美亚洲免费在线| 欧美精品尤物在线| 国一区二区在线观看| 亚洲午夜av电影| 欧美freesex8一10精品| 亚洲尤物视频在线| 欧美日韩在线视频一区| 亚洲国产成人一区| 久久久不卡网国产精品一区|