2016-04-28 5 views
0

Ich mache eine Menüleiste, die Menüelemente aufnimmt. Ich möchte das Fenster, das die Menüleiste enthält, um zu entscheiden, wie das Verhalten eines Menüelements sein wird. Ich möchte also, dass das Fenster eine Funktion an den Menüpunkt weitergibt.Speichern eines Funktionszeigers in einem Mitglied einer Klasse

ist mein bester Versuch mir diesen Fehler:

error: no matching function for call to 'MenuItem::setBehaviour(void (MyWindow::*)())' 

Hier ist MenuItem.h:

class MenuItem{ 
public: 
    typedef void (sf::RenderWindow::*function_type)(); 

    MenuItem(sf::RenderWindow* win); // window that holds the menu bar 

    void setBehaviour(function_type f); // I want to be able to change the behaviour 
             // to reuse the menu item 
    void action(); // use the function 

private: 
    sf::RenderWindow* m_window; 
    function_type  m_function; 
}; 

MenuItem.cpp

MenuItem::MenuItem(sf::RenderWindow* win) : m_window(win) 
{ 
    //ctor 
} 

void MenuItem::setBehaviour(function_type f) 
{ 
    m_function = f; 
} 

void MenuItem::action() 
{ 
    (m_window->*m_function)(); 
} 

Das Fenster, das die Menüleiste hinzufügt :

class MyWindow : public sf::RenderWindow 
{ 
    //... 
    void close(); 
}; 

Und das CPP-Datei des Fensters:

MyWindow::MyWindow() : sf::RenderWindow(...) 
{ 
    //... 
    MenuItem item(this); 
    item.setBehaviour(&MyWindow::close); // error! 
    //... 
} 

//... 

void MyWindow::close() 
{ 
    this->close(); 
} 
+0

Nun, die Funktionszeiger Sie versuchen, es zu passieren ist kein Mitglied von 'sf :: RenderWindow' sondern stammt aus einer abgeleiteten Klasse. –

+0

Ah ... Ich habe Ihren Kommentar bis jetzt nicht gesehen. Danke, das hat den Trick gemacht. – MrMxyztplk

Antwort

0

Die beiden gegebenen Antworten waren über meinen Kopf ein wenig. Ich habe einige Zeit mit der std :: -Funktion von Jan verbracht und dabei ein wenig mehr gelernt. Hier ist, was ich falsch gemacht habe:

Die Funktionen für MenuItem kommen aus MyWindow, nicht sf :: RenderWindow, also muss ich MyWindow deklarieren und alle sf :: RenderWindows zu MyWindow ändern.

class MyWindow; // fix: forward declaration 
class MenuItem{ 
    public: 

    typedef void (MyWindow::*function_type)(); // fix 

    MenuItem(MyWindow* win); // fix 

    void setBehaviour(function_type f); 

    void action(); 

private: 
    MyWindow* m_window; // fix 
    function_type  m_function; 
}; 

MenuItem.cpp

MenuItem::MenuItem(MyWindow* win) : m_window(win) // fix 
{ 
    //ctor 
} 
0

Was könnten Sie versuchen zu lösen, das ist MenuItem eine Templat-Klasse zu machen:

template<typename RenderWindow> 
class MenuItem{ 
public: 
    typedef void (RenderWindow::*function_type)(); 

    MenuItem::MenuItem(RenderWindow* win) 
    : m_window(win) { 
     std::static_assert(
      std::is_base_of<sf::RenderWindow,RenderWindow>() 
          ,"RenderWindow must be derived from sf::RenderWindow."); 
    } 

    void setBehaviour(function_type f) { 
     m_function = f; 
    } 

    void action() { 
     m_window->*m_function)(); 
    } 

private: 
    RenderWindow*  m_window; 
    function_type  m_function; 
}; 

auslassen die MenuItem.cpp vollständig Datei.

können Sie instanziieren und Zugriff auf eine MenuItem wie

MyWindow myWindow; 
MenuItem<MyWindow> closeWindow(myWindow); 
menuItem.setBehavior(MyWindow::close); 

// ... 
menuItem.action(); 

dann.

0

Sie könnten std::function dafür verwenden:

// MenuItem.h 
#include <functional> 

class MenuItem 
{ 
    public: 
     using function_type = std::function<void()>; 
     auto setBehaviour(function_type f) -> void; 
     auto action() -> void; 

    private: 
     function_type m_function; 
}; 

// MenuItem.cpp 
auto MenuItem::setBehaviour(function_type f) -> void 
{ 
    m_function = f; 
} 

auto MenuItem::action() -> void 
{ 
    m_function(); 
} 

// MyWindow.cpp 
#include <functional> 

MyWindow::MyWindow() : sf::RenderWindow(...) 
{ 
    MenuItem item(this); 
    item.setBehaviour(std::bind(&MyWindow::close, this)); 
} 

auto MyWindow::close() -> void 
{ 
    // do something 
} 
Verwandte Themen