boost::bind(&memberfunction, obj, _1, _2........)類似這樣的用法,我們叫做成員函數(shù)綁定,boost庫的文檔中說的很清楚,第一個參數(shù)可以是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);
由上面的代碼可以看出,我們可以隨便傳任意一種類對象的形式,函數(shù)模板會自動尋找最為匹配的為我們實現(xiàn)。但是有兩種情況是特殊的,即:
1、該對象不可進行拷貝構(gòu)造函數(shù)。
2、該對象不可隨意被析構(gòu)。
發(fā)現(xiàn)這個問題是在我編寫單件模式時的遇見的,當時發(fā)現(xiàn)我的單件對象在bind中被析構(gòu)了一次,這很不尋常,為什么bind會調(diào)用第一個參數(shù)的析構(gòu)呢?跟蹤進了boost的源碼才發(fā)現(xiàn),原來所有的參數(shù)都會被拷貝一遍,然后析構(gòu)一遍,這樣一來,我們傳遞參數(shù)的時候就會有一些小麻煩了,首先必須保證參數(shù)能夠被拷貝而不影響邏輯和數(shù)據(jù)一致性,其次,參數(shù)能夠被析構(gòu)而不影響邏輯和數(shù)據(jù)一致性。單件是全局性質(zhì)的數(shù)據(jù),所以絕對不可以析構(gòu),那么這種情況的話,我們只好傳遞單件對象的地址,而不能傳遞值或引用。
另:附上出錯問題的代碼如下
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;
}
