Probleme bei OOP mit Boost::Signals



  • Hallo,

    ich schreibe zurzeit ein Framework oder so :), für 2D Games mit SFML.
    Für Signals und Slots habe ich boost gewählt und da hab ich ein Problemm.

    Hier ist mal der Code den ich vereinfacht nachgebaut habe:

    // Item.h
    
    #ifndef ITEM
    #define ITEM
    
    #include <boost/signals.hpp> 
    #include <boost/bind.hpp>
    
    class Item{
    
    public:
    	typedef boost::signal<void(int)> MySlot;
    	MySlot mySlot;
    
    	void SetClick(MySlot::slot_function_type sf);	
    	void Click();
    
    	Item();
    };
    
    #endif
    
    // Item.cpp
    
    #include "Item.h"
    
    Item::Item(){
    }
    
    void Item::SetClick(MySlot::slot_function_type sf){
    	mySlot.connect(sf);
    }
    
    void Item::Click(){
    	mySlot(1);
    }
    
    // Gui.h
    
    #ifndef GUI
    #define GUI
    
    #include "Item.h"
    #include <vector>
    
    class App;
    
    class Gui{
    
    public:
    	std::vector<Item*> items;
    
    	App *parent;
    
    	void SetParent(App *parent_);
    	void AddItem(Item *item_);
    	Item *GetItem(int index);
    	void GuiClose(int gui_do = -1);
    
    };
    
    #endif
    
    // Gui.cpp
    
    #include "Gui.h"
    #include "App.h"
    
    void Gui::SetParent(App *parent_){
    	parent = parent_;
    }
    
    void Gui::AddItem(Item *item_){
    	items.push_back(item_);
    }
    
    Item *Gui::GetItem(int index){
    	return items[index];
    }
    
    void Gui::GuiClose(int gui_do){
    	parent->SetIndex(gui_do);
    }
    
    // App.h
    
    #ifndef APP
    #define APP
    
    #include <vector>
    #include "Gui.h"
    #include <iostream>
    
    class App{
    
    public:
    	std::vector<Gui*> guis;
    	Gui *gui;
    	int index;
    
    	void AddGui(Gui *gui_);
    	void SetIndex(int index_);
    	void Run(int index_);
    };
    
    #endif
    
    // App.cpp
    
    #include "App.h"
    
    void App::AddGui(Gui *gui_){
    	gui_->SetParent(this);
    	guis.push_back(gui_);
    }
    
    void App::SetIndex(int index_){
    	index = index_;
    	std::cout << index_ << std::endl;
    }
    
    void App::Run(int index_){
    	index = index_;
    	gui = guis[index];
    
    	Item *item = gui->GetItem(0);
    	item->Click();
    
    	//gui->GuiClose(200);
    }
    
    // main.cpp
    
    #include "Item.h"
    #include "Gui.h"
    #include "App.h"
    
    #include <boost/bind.hpp> 
    
    int main(){
    
    	Gui *gui0 = new Gui();
    	{
    		Item *item0 = new Item();
    		Item *item1 = new Item();
    		Item *item2 = new Item();
    		gui0->AddItem(item0);
    		gui0->AddItem(item1);
    		gui0->AddItem(item2);
    
    		item0->SetClick( boost::bind(&Gui::GuiClose, *gui0, 10) );
    	}
    
    	Gui *gui1 = new Gui();
    	{
    		Item *item0 = new Item();
    		Item *item1 = new Item();
    		Item *item2 = new Item();
    		gui1->AddItem(item0);
    		gui1->AddItem(item1);
    		gui1->AddItem(item2);
    	}
    
    	App app;
    	app.AddGui(gui0);
    	app.AddGui(gui1);
    
    	app.Run(0);
    
    	return 0;
    }
    

    In "main.cpp" Zeile 21 connecte ich die Methode "Gui::GuiClose()" die ich später in "App::Run()" über die Methode "Item::Click()" aufrufe. Die Methode "Gui::GuiClose()" greift auf die Methode "App::SetIndex()" über den "parent" und da hab ich das Problem. Der "parent" ist "NULL" obwohl ich diesen in der Methode "App::AddGui()" setze.
    Wenn ich "Gui::GuiClose()" ohne das connecten aufrufe dan ist der "parent" nicht NULL.



  • ghostboss schrieb:

    item0->SetClick( boost::bind(&Gui::GuiClose, *gui0, 10) );
    

    Hier wird eine Kopie von *gui0 erstellt. Und diese Kopie wird niemals App hinzugefügt.

    Dies sollte Abhilfe schaffen:

    boost::ref(*gui0)
    

Log in to reply