2015-02-08 45 views
1

我正在C++創建一個控制檯菜單,我想給我的菜單中的每個項目一個回調函數,所以當一個項目被選中時,一個不同的函數被調用。 到目前爲止,我有這樣的代碼:C++成員函數指針從其他類

#include <iostream> 
#include <vector> 

using namespace std; 

class Core 
{ 
    public: 

    void action1() {} 

    void action2() {} 
    //... 
}; 

typedef void (Core::*CoreFunc)(); 

class Menu 
{ 
    struct Option 
    { 
     Option(CoreFunc cb) : callback(cb) {} 
     //some data 
     CoreFunc callback; 
     //some more data 
    }; 

    vector<Option> m_options; 

    public: 

    Menu(Core const& core) 
    { 
     addOption(core.action1); 
    } 

    void addOption(CoreFunc callback) 
    { 
     m_options.push_back(Option(callback)); 
    } 

    void execOptionX(int index) 
    { 
     m_options[index].callback(); 
    } 
}; 

int main() 
{ 
    Core core; 

    Menu menu(core); 

    menu.execOptionX(0); 

    return 0; 
} 

這是給我這個錯誤:

no matching function for call to ‘Menu::addOption(<unresolved overloaded function type>)’ 

addOption(core.action1);

must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((Menu*)this)->Menu::m_options.std::vector<_Tp, _Alloc>::operator[]<Menu::Option, std::allocator<Menu::Option> >(((std::vector<Menu::Option>::size_type)index)).Menu::Option::callback (...)’, e.g. ‘(... ->* ((Menu*)this)->Menu::m_options.std::vector<_Tp, _Alloc>::operator[]<Menu::Option, std::allocator<Menu::Option> >(((std::vector<Menu::Option>::size_type)index)).Menu::Option::callback) (...)’ 

當我嘗試打電話功能。

我見過很多成員函數指針的實現,但它們都在同一個類中使用。

爲什麼我會收到這些錯誤?

讓這段代碼編譯/工作的正確語法是什麼?

謝謝

回答

2

你宣佈CoreFunc作爲一個非靜態指針到成員方法。所以,你需要指定一個指向所需的方法,如:

addOption(&Core::action1); 

更重要的是,你還需要提供一個Core對象實例作爲this參數回調。您可以指定通過.*操作的對象(如果使用對象引用)或->*操作(如果使用一個對象指針),例如:

void execOptionX(int index) 
{ 
    CoreFunc callback = m_options[index].callback; 
    (SomeCoreObj.*callback)(); 
} 

void execOptionX(int index) 
{ 
    CoreFunc callback = m_options[index].callback; 
    (SomeCoreObjPtr->*callback)(); 
} 

所以,你需要改變你的Menu類跟蹤將被傳遞給回調的Core對象的(假設你沒有想通過Core對象作爲參數傳遞給execOptionX(),如:

class Menu 
{ 
    struct Option 
    { 
     Option(CoreFunc cb) : callback(cb) {} 
     //some data 
     CoreFunc callback; 
     //some more data 
    }; 

    Core &m_core; 
    vector<Option> m_options; 

public: 

    Menu(Core &core) 
     : m_core(core) 
    { 
     addOption(&Core::action1); 
    } 

    void addOption(CoreFunc callback) 
    { 
     m_options.push_back(Option(callback)); 
    } 

    void execOptionX(int index) 
    { 
     CoreFunc callback = m_options[index].callback; 
     (m_core.*callback)(); 
    } 
}; 

當然,Core對象必須在Menu(它在您的main()示例中)的生命週期內保持活動狀態。

+0

好的,我在我的'Menu'類中加了'Core&m_core',並糾正了'addOption(&Core :: action1);'。然而,當我做'm_core。* callback();'時,我仍然在'callback(...)'中調用'must use'。*'或' - > *'來調用指向成員函數的指針。 ,例如'(... - > * callback)(...)'' – Oliver 2015-02-08 06:04:05