2011-06-09 94 views
1

我需要一些狀態映射到類的特定成員函數,用於(一個非常減少)例如:函數指針實例成員

class Z { 
    _a_ptr_to_some_member _p; 

    void UpdateGuiForStopState(State s) { 
     // do something with state 
    } 

    Z() { 
     // setup _p to point to UpdateGuiForStopState 
    } 

    void StateComesInHere(State s) { 
     if(s.id == STOP_ID) { // eventually use lookup 
     _p(s); 
     } 
    } 
} 

只需使用STL(不能使用第三黨東西像升壓),什麼是_a_ptr_to_some_member的類型,我如何綁定的方法UpdateGuiForStopState呢?

大概我使用STL mem_xxx的東西,但不能工作如何。

是的,我能做到這一點一百和另外一個不同的方式,但我想看看,如果這種方式是可行的。

回答

1

使用STL的bind1stmem_fun

class Z3 { 
    typedef std::mem_fun1_t<void,Z3,State> _a_ptr_to_some_member_raw; 
    typedef std::binder1st<_a_ptr_to_some_member_raw> _a_ptr_to_some_member; 
    _a_ptr_to_some_member _p; 

    void UpdateGuiForStopState(State s) { 
     // do something with state 
    } 

    Z3() : _p(std::bind1st(std::mem_fun(&Z3::UpdateGuiForStopState), this)) 
    { 
    } 

    void StateComesInHere(State s) { 
     if(s.id == STOP_ID) { // eventually use lookup 
     _p(s); 
     } 
    } 
}; 
1

您可以直接用裸指針成員做到這一點:

typedef void (Z::*_a_ptr_to_some_member)(State s); 
_a_ptr_to_some_member _p; 
... 
_p = &Z::UpdateGuiForStopState; 
... 
(this->*_p)(s); 

這是一個有點老同學這些天,語法有點毛茸茸,但它應該工作。 (警告:我還沒有嘗試過。)

第一比特定義了正確類型的指針成員函數,並聲明類型的成員變量。

第二位初始化_p指向正確的函數(你不能縮短這個,這是必要的語法)。

第三位調用成員函數指向_p;要做到這一點,你必須提供Z的實例 - 在這種情況下,一個由該指向。我認爲需要額外的括號。運營商的優先權有點怪異。

TBH我可能會使用綁定(從升壓,TR1,或C++ 11),用於此;它稍微慢一點,但更容易和更靈活。

1

如果您沒有C++ 0x/TR1支持,則應該使用std::functionboost::function。使用起來會使用boost::bindstd::bind最簡單的方法,當boost::bind是更好更簡單,我不會使用標準的bind1st和這樣的爛攤子。

0

這裏是一個工作示例(參見http://ideone.com/VEmRZ):

#include <iostream> 

typedef enum { s0, s1, s2 } State ; 

class Z { 
public: 
    void f0 (State s) { std::cout << "f0" << std::endl ; } 
    void f1 (State s) { std::cout << "f1" << std::endl ; } 
} ; 

typedef void (Z::*_a_ptr_to_some_member)(State s); 

int main() 
    { 
    Z z ; 
    _a_ptr_to_some_member _p = &Z::f0 ; 
    (z.*_p)(s0) ; 
    _p = &Z::f1 ; 
    (z.*_p)(s2) ; 
    }