2012-07-14 136 views
2

我想創建一個事件處理系統,其中對象可以訂閱由其他對象廣播的事件,並在該事件被廣播時調用方法。我試圖用一個稱爲EventHandler的單例類來實現它。對象調用他們訂閱事件由某個對象播出EventHandler的公共方法:使用基類的通用方法指針來調用派生類的方法

void startWatchingObjectEvent(PDObject * object, PDEvent event, PDObject* listener, PDReceiver receiver); 

PDObject是將由EventHandler處理的所有對象的基類。 PDEvent只是標識事件的唯一字符串。

PDReceiver是我遇到問題的地方。我有它typedef定義的方法指針上PDObject類:

typedef void (PDObject::*PDReceiver)(PDObject*, PDEvent); 

現在PDObject類本身並沒有真正有PDObject將那EventHandler會調用任何方法,但派生類,和我想要創建EventHandler可以存儲的泛型類型,該類型適用於任何派生類PDObject。我實現EventHandler這種方式,試圖編寫單元測試,以確保它的工作好:

const PDEvent Test_PokeEvent = "Test_PokeEvent"; 

void Test_EventHandler_sendObjectMessage() 
{ 
    EventHandler& eventh = EventHandler::instance(); 
    Test_PDObject caster; 
    Test_PDObject listener; 
    PDReceiver receiver = &Test_PDObject::test_poke; 
    eventh.startWatchingObjectEvent(&caster, Test_PokeEvent, &listener, (listener.*receiver)(&caster, Test_PokeEvent)); 
    eventh.sendObjectEvent(&caster, Test_PokeEvent); 
    assert(listener.test_wasPoked()); 
} 

Test_PDObject是一個派生類的PDObject,只是一個翻轉位wasPokedtest_poke被調用。

的問題是,編譯器不喜歡我努力的Test_PDObject方法分配給PDReceiver因爲PDReceiver被定義爲PDObject的方法類型。

我試圖做甚至可能嗎?我可以使用這個泛型方法指針類型來引用派生類的方法嗎?或者我的方法完全有缺陷?

編輯:我想通了,我可以用static_cast派生類的方法指針轉換爲基類的方法指針像這樣:

PDReceiver receiver = static_cast<PDReceiver>(&Test_PDObject::test_poke); 

到目前爲止這麼好!我的單元測試現在正在完美運行。

+0

你不應該更新的答案的問題,而是將其標記張貼的答案爲*接受*的一個,或回答自己的問題和標記後爲*公認*。 – 2012-07-16 06:11:11

+0

好的。我是新來的,所以謝謝你讓我知道。 :) – eyebrowsoffire 2012-07-17 06:36:50

回答

1

一個的static_cast確實是需要投全部指針到成員Child::*類型的輸入Base::*,但請記住,如果你不小心使用指針到這可能是相當危險的 - 在Base(而不是相關的Child)的實例上成員


在下面,我們使用相同的確切方法如前面所述,儘管主叫Base類型的對象上Child::func的例子是導致未定義行爲,因爲我們正在訪問基地的不存在構件在函數內部。

struct Base { 
    /* ... */ 
}; 

struct Child : Base { 

    void func() { 
    this->x = 123; 
    } 

    int x; 
}; 

int 
main (int argc, char *argv[]) 
{ 
    typedef void (Base::*BaseFuncPtr)(); 

    BaseFuncPtr ptr_to_child_func = static_cast<BaseFuncPtr> (&Child::func); 

    Base b; 

    (b.*ptr_to_child_func)(); /* undefined-behavior */ 
} 
相關問題