Pointer auf Element einer Liste



  • Hi,

    Ich habe eine Klasse "MainMenu" die eine Liste (std::list) von "ScrollableList"-Objekten hat, und einen Pointer der auf eines der Objekte in der Liste zeigen soll. Zudem hat die Klasse die Methode "add_menu()", die ein "ScrollableList"-Objekt erzeugt und in die std::list einfügt, einen Konstruktor der 1x "add_menu()" aufruft und den Pointer auf dieses Menü zeigen lässt, und eine Methode "btn_up_down()" die dann über den Pointer eine Methode des referenzierten Objektes aufruft die in dem Objekt einfach eine Variable verändert. Hinterher kann ich dann sehen ob die Variable verändert wurde oder nicht.

    MainMenu.h:

    class MainMenu {
    
    private:
    	static std::list<ScrollableList> menu_list;
    	ScrollableList* active_menu;
    
    public:
    	MainMenu();
    
    	void add_menu();
    
    	void btn_up_down();
    };
    

    MainMenu.cpp:

    void MainMenu::add_menu() {
    	// Fügt einfach ein "ScrollableList"-Objekt der menu_list hinzu
    }
    
    MainMenu::MainMenu()
    {
    	this->add_menu();
    	this->active_menu = &(menu_list.back());
    }
    
    void MainMenu::btn_up_down() {
    	this->active_menu->set_active_element(1);
    }
    

    Er schein aber nichts zu verändern. Er stürzt aber auch nicht ab oder so. Jemand ne Ahnung woran das liegen könnte?



  • Was meinst Du denn, was Dir dieser Ausdruck liefert?

    &(menu_list.back())
    

    Und was möchtest Du haben?



  • jencas schrieb:

    Was meinst Du denn, was Dir dieser Ausdruck liefert?

    &(menu_list.back())
    

    Und was möchtest Du haben?

    Die Adresse von dem Objekt das .back() zurückgibt. Ich habe das mittlerweile auch geändert, die Liste ist jetzt nicht mehr eine Liste von ScrollableList sondern von ScrollableList*. Ich mach dann auch

    MainMenu::MainMenu()
    {
        this->add_menu();
        this->active_menu = menu_list.back();
    }
    
    void MainMenu::btn_up_down() {
        this->active_menu->set_active_element(1);
    }
    

    Aber es passiert einfach nichts.



  • Ist denn der Zeiger dort gültig?



  • ist ne Membervariable von MainMenu, sollte dann also doch oder?

    Luke-2 schrieb:

    MainMenu.h:

    class MainMenu {
    
    private:
    	static std::list<ScrollableList> menu_list;
    	ScrollableList* active_menu;
    
    public:
    	MainMenu();
    
    	void add_menu();
    
    	void btn_up_down();
    };
    


  • Luke-2 schrieb:

    ist ne Membervariable von MainMenu, sollte dann also doch oder?

    Kommt drauf an, wann du dem was zuweist. 😉
    Und ob das Objekt noch gültig ist.



  • Also im Konstruktor der Klasse (siehe erster Post) weis ich dem was zu

    drakon schrieb:

    Luke-2 schrieb:

    ist ne Membervariable von MainMenu, sollte dann also doch oder?

    Und ob das Objekt noch gültig ist.

    Ich erstelle in der Methode void add_menu() mit new ein neues ScrollableList Objekt was ich nirgends delete, dann sollte es doch, wie du auch meintest noch gültig sein...

    void MainMenu::add_menu() {
    
    	ScrollableList *neueliste = new ScrollableList();
    	this->menu_list.push_back(neueliste);
    }
    
    MainMenu::MainMenu()
    {
    	this->add_menu();
    	this->active_menu = menu_list.back();
    }
    
    void MainMenu::btn_up_down() {
    	this->active_menu->set_active_element(1);
    }
    

    Sry, ich kapier's wohl nicht...



  • static std::list<ScrollableList> menu_list;
       // ...
    
       ScrollableList *neueliste = new ScrollableList();
       this->menu_list.push_back(neueliste);
    

    Weshalb kompiliert das überhaupt? Hat dein ScrollableList einen Konstruktor, der ScrollableList* als Argument nimmt? Willst du nicht eher Zeiger auf die Listen in deiner std::list speichern?



  • Decimad schrieb:

    static std::list<ScrollableList> menu_list;
       // ...
    
       ScrollableList *neueliste = new ScrollableList();
       this->menu_list.push_back(neueliste);
    

    Weshalb kompiliert das überhaupt? Hat dein ScrollableList einen Konstruktor, der ScrollableList* als Argument nimmt? Willst du nicht eher Zeiger auf die Listen in deiner std::list speichern?

    Ja will ich. Tu ich das nicht wenn ich "ScrollableList ->*<-neueliste" erstelle und in die list pushe?



  • Nein, weil du ja in der Deklaration von menu_list sagst, dass die std::list Objektinstanzen speichert (Also keine Zeiger).
    Denke dann daran, die Objekte mit delete auch wieder zu zerstören, bevor menu_list zerstört wird.



  • Decimad schrieb:

    Nein, weil du ja in der Deklaration von menu_list sagst, dass die std::list Objektinstanzen speichert (Also keine Zeiger).
    Denke dann daran, die Objekte mit delete auch wieder zu zerstören, bevor menu_list zerstört wird.

    Achso, ja siehe Post http://www.c-plusplus.net/forum/viewtopic-var-p-is-1643969.html#1643969 . Ich hab das mittlerweiele so:

    MainMenu.h:

    class MainMenu {
    
    private:
    	static std::list<ScrollableList*> menu_list;
    	ScrollableList* active_menu;
    

    // [...]
    };[/cpp]

    MainMenu.cpp:

    void MainMenu::add_menu() {
    	ScrollableList *neueliste = new ScrollableList();
    	menu_list.push_back(neueliste);	
    
    	// menu_list.back()->set_active_element(2); // würde funktionieren
    }
    
    MainMenu::MainMenu()
    {
    	this->add_menu();
    	this->active_menu = menu_list.back();
    }
    
    void MainMenu::btn_up_down() {
    
    	this->active_menu->set_active_element(1);  // bewirkt nichts
    }
    

    Was halt ne Sache ist, was hier im Comment steht, ein "set_active_element(2)" in add_menu() geht, aber in btn_up_down() nicht mehr. Also entweder das Objekt ist nicht mehr gültig oder das mit den Pointern ist nicht richtig.



  • Luke-2 schrieb:

    Achso, ja siehe Post http://www.c-plusplus.net/forum/viewtopic-var-p-is-1643969.html#1643969 . Ich hab das mittlerweiele so:

    In deiner Variante fehlen mehrere Dinge (kann aber daran liegen das man nur einen Teilausschnitt sieht).

    1. Wo löschst du die Elemente der Liste wieder?
    2. Bedenkst du das vielleicht ausversehen Kopiekonstruktor und Zuweisungsoperator verwendet werden (Würde ich immer wenn es um Zeiger geht von vorne herein bedenken)?
    Im Zweifel diese beiden privat deklarieren ohne eine Implementierung. Dann wird der Compiler schon meckern wenn sie doch aufgerufen werden.

    class MainMenu {
      private:
        // Kopie und Zuweisung unterbinden (nicht implementieren):
        MainMenu(MainMenu const &);
        MainMenu& operator=(MainMenu const &);
    

    cu André



  • Ich wollte die in einer weiteren funktion remove_menu() löschen, wo neben dem noch ein paar andere Dinge gemacht werden. Danke für die konstruktor/kopiesache, hab ich jetzt eingebaut.



  • Also es scheint ein problem mit dem pointer this->active_menu zu sein.

    Wenn ich in void MainMenu::btn_down_down() direkt

    menu_list.back()->set_active_element(3);
    

    Schreibe, klappts. Ich frag mich nur warum geht's nicht. Da kopier ich doch einfach nur den Pointer in der menu_list nach active_menu, oder nicht?

    MainMenu::MainMenu()
    {
    	this->add_menu();
    	this->active_menu = menu_list.back();
    }
    


  • Luke-2 schrieb:

    Ich wollte die in einer weiteren funktion remove_menu() löschen, wo neben dem noch ein paar andere Dinge gemacht werden...

    Grundsätzlich solltest du dich noch mit einigen Programmiertechniken vertraut machen. Code sollte möglichst so geschrieben werden, das Fehlbedienungen weitgehend ausgeschlossen werden können.

    Ich persönlich mag Konstrukte wie add_menu, remove_menu nicht, weil man leicht mal das remove_menu vergessen kann. Techniken die sowas angehen sind z.B. RAII.

    Das Prinzip hierbei ist das man mit Objekten arbeitet die Ressourcen beim Destruktoraufruf wieder freigeben. Ein Beispiel dieser Technik sind z.B. auch Smartpointer wie z.B. die der boost-Bibliothek, konkret Dieser Bestandteil (Teilweise in den TR1 sowie in den nächsten C++ Standard C++0x übernommen).



  • Ja ich weiß dass da einiges noch nicht ordentlich ist, mach das auch noch nicht so lang.


Anmelden zum Antworten