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

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 釀妹汁 閱讀(5839) 評論(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>
            欧美mv日韩mv国产网站| 欧美日韩中文在线| 国产揄拍国内精品对白| 欧美一区精品| 欧美在线首页| 亚洲高清在线| 91久久中文| 欧美色欧美亚洲另类二区 | 欧美在线日韩精品| 国内精品久久久久久久影视蜜臀| 久久九九免费| 欧美xxx在线观看| 亚洲桃花岛网站| 性欧美videos另类喷潮| 尤物九九久久国产精品的特点| 欧美成人中文| 国产精品成人aaaaa网站 | 在线成人免费观看| 亚洲激情视频在线| 国产精品入口夜色视频大尺度| 久久福利毛片| 欧美精彩视频一区二区三区| 亚洲综合色噜噜狠狠| 久久精品最新地址| 一本大道久久a久久精二百| 亚洲中无吗在线| 亚洲区一区二区三区| 亚洲视频在线观看免费| 激情综合电影网| 宅男在线国产精品| 亚洲高清不卡av| 亚洲伊人观看| 亚洲精品一区二区三区蜜桃久| 亚洲淫性视频| 99热免费精品在线观看| 欧美在线视频一区二区| 国产精品99久久99久久久二8| 欧美亚洲自偷自偷| 亚洲影院污污.| 农村妇女精品| 久久久久成人精品免费播放动漫| 欧美精品在线一区二区三区| 久久亚洲综合色| 国产精品女主播一区二区三区| 欧美高清一区二区| 韩日午夜在线资源一区二区| 一区二区三区毛片| 99国产一区二区三精品乱码| 久久久久久久性| 欧美中文字幕视频| 欧美亚洲第一页| 亚洲精品久久久久久久久| 永久免费视频成人| 久久精品国产亚洲a| 午夜宅男久久久| 国产精品成人一区二区三区夜夜夜| 亚洲第一中文字幕| 狠狠久久综合婷婷不卡| 午夜欧美大尺度福利影院在线看| 亚洲免费综合| 欧美午夜性色大片在线观看| 亚洲精品欧美| 亚洲国产高清高潮精品美女| 久久久999国产| 免费短视频成人日韩| 国产综合色精品一区二区三区| 午夜精品久久久久久99热| 亚洲男人的天堂在线| 国产精品九九| 亚洲欧洲av一区二区| 午夜久久久久久| 国产酒店精品激情| 欧美一区二区三区免费视频| 欧美在线一区二区三区| 国产亚洲成av人片在线观看桃| 亚洲无线一线二线三线区别av| 亚洲欧美视频在线| 国产午夜精品视频免费不卡69堂| 午夜精品理论片| 久久天天综合| 91久久精品国产91久久性色tv| 欧美成人一区二区三区片免费| 亚洲国产成人高清精品| 亚洲精选视频免费看| 欧美日韩一区二区三区免费| 正在播放欧美视频| 久久精品在线视频| 亚洲国产成人不卡| 欧美日韩精品在线视频| 亚洲欧美不卡| 欧美va天堂在线| 一区二区三区欧美日韩| 国产九九视频一区二区三区| 久久久久久网| a91a精品视频在线观看| 久久成人18免费网站| 亚洲国产一区二区a毛片| 欧美日韩在线观看一区二区| 香蕉视频成人在线观看| 欧美激情视频在线免费观看 欧美视频免费一 | 欧美日韩国产va另类| 亚洲在线第一页| 男男成人高潮片免费网站| 一本大道久久a久久综合婷婷 | 久久理论片午夜琪琪电影网| 亚洲国产精品一区二区www| 国产精品99久久久久久www| 国产日产精品一区二区三区四区的观看方式 | 国产精品中文在线| 欧美成年人网站| 亚洲欧美电影在线观看| 亚洲电影激情视频网站| 性欧美超级视频| 亚洲精品一区二区三区不| 国产伦精品一区| 欧美日韩国内| 美女日韩在线中文字幕| 亚洲欧美日韩综合一区| 亚洲福利视频三区| 久久日韩粉嫩一区二区三区| 亚洲伊人观看| 日韩视频二区| 亚洲高清免费视频| 国产手机视频一区二区| 欧美日韩亚洲国产一区| 久久综合网色—综合色88| 午夜天堂精品久久久久| 一本久道久久综合狠狠爱| 欧美激情精品久久久久久久变态 | 亚洲精品欧美专区| 红桃视频亚洲| 国产一区二区久久精品| 国产精品久久久亚洲一区| 欧美精品一区二区三| 久久久噜噜噜久久狠狠50岁| 性欧美长视频| 亚洲男人的天堂在线| 一区二区三区四区国产| 亚洲精品裸体| 亚洲精选大片| 99国产精品久久久久久久久久| 亚洲国产婷婷香蕉久久久久久| 美女精品自拍一二三四| 巨乳诱惑日韩免费av| 久久人人97超碰国产公开结果| 欧美影院在线播放| 欧美中文字幕不卡| 久久久91精品国产一区二区三区| 欧美在线观看一区二区三区| 欧美亚洲免费高清在线观看| 亚洲欧美日韩天堂一区二区| 亚洲欧美一级二级三级| 欧美一二三区在线观看| 午夜久久美女| 久久久久九九九| 麻豆国产精品一区二区三区 | 亚洲精品在线免费观看视频| 亚洲日本成人网| 在线亚洲观看| 先锋资源久久| 久久亚洲免费| 亚洲春色另类小说| 激情欧美丁香| 伊人成人在线视频| 亚洲国产欧美精品| 亚洲日韩欧美视频| 亚洲视频中文| 久久久久久久综合色一本| 麻豆精品视频| 亚洲精品午夜| 午夜视频在线观看一区| 久久日韩粉嫩一区二区三区| 欧美成人r级一区二区三区| 欧美日韩精品二区| 国产精品一区二区三区乱码| 狠狠色狠狠色综合日日tαg| 亚洲国产一区视频| 亚洲自拍三区| 欧美成人国产va精品日本一级| 亚洲每日在线| 午夜久久久久久| 欧美+日本+国产+在线a∨观看| 欧美日韩和欧美的一区二区| 国产日韩精品一区二区三区在线| 亚洲国产欧美日韩| 欧美一级大片在线免费观看| 欧美激情精品久久久久久黑人| 亚洲午夜av在线| 欧美大色视频| 国产综合久久久久久| 一本色道久久综合狠狠躁篇怎么玩 | 欧美国产一区二区在线观看| 国产精品亚洲一区| 亚洲精品一区二区三区不| 欧美在线视频网站| 亚洲人成人一区二区在线观看| 欧美专区中文字幕| 国产精品久久久对白| 亚洲免费观看| 老司机精品导航|