2011-03-31 208 views
3

考慮下面的類C++成員函數指針

class Foo 
{ 
    typedef bool (*filter_function)(Tree* node, std::list<std::string>& arg); 

    void filter(int filter, std::list<std::string>& args) 
    { 
     ... 
     if (filter & FILTER_BY_EVENTS) { 
      do_filter(events_filter, args, false, filter & FILTER_NEGATION); 
     } 
     ... 
    } 

    void do_filter(filter_function ff, std::list<std::string>& arg, 
     bool mark = false, bool negation = false, Tree* root = NULL) 
    { 
     ... 
    } 

    bool events_filter(Tree* node, std::list<std::string>& arg) 
    { 
     ... 
    } 
}; 

我可以通過events_filter作爲參數向do_filter只有當events_filterstatic構件。但我不想讓它變成static。有沒有辦法可以將指向成員函數的指針傳遞給另一個函數?可能會使用boost庫(如函數)左右。

謝謝。

回答

12

bool (Foo::*filter_Function)(Tree* node, std::list<std::string>& arg)
會給你一個成員函數指針。您傳遞一個有:

Foo f; 
f.filter(&Foo::events_filter,...); 

而且與調用它:跟隨你的語法

(this->*ff)(...); // the parenthesis around this->*ff are important 

如果你希望能夠通過任何類型的函數/仿函數,使用Boost.Function,或者如果你的編譯器支持它,使用std :: function。

class Foo{ 
    typedef boost::function<bool(Tree*,std::list<std::string>&)> filter_function; 

    // rest as is 
}; 

然後傳遞任何你想要的。一個仿函數,一個免費的功能(或靜態成員函數),或者甚至Boost.Bind或std :: bind的非靜態成員函數(同樣,如果你的編譯器支持的話):

Foo f; 
f.do_filter(boost::bind(&Foo::events_filter,&f,_1,_2),...); 
+1

請參閱C++常見問題解答精簡版詳細解釋「指向成員函數」:http://www.parashift.com/c++-faq-lite/pointers-to-members.html – 2011-03-31 11:40:21

+0

是的,那是按預期工作。謝謝 – maverik 2011-03-31 11:47:53

+0

完美無瑕。 – 2011-03-31 11:54:10

2
//member function pointer is declared as 
bool (*Foo::filter_function)(Tree* node, std::list<std::string>& arg); 

//Usage 

//1. using object instance! 
Foo foo; 
filter_function = &foo::events_filter; 

(foo.*filter_function)(node, arg); //CALL : NOTE the syntax of the line! 


//2. using pointer to foo 

(pFoo->*filter_function)(node, arg); //CALL: using pFoo which is pointer to Foo 

(this->*filter_function)(node, arg); //CALL: using this which is pointer to Foo