Objektpointer und der Gültigkeitsbereich...



  • Stillmrkralo schrieb:

    Also wie ich es verstehe ist vector ein behälter wo ich die erstellten objekte aneinanderhänge. In die spitzen klammer kommt der klassenname und dann kann ich den container zurückgeben?

    In den spitzen Klammern steht der Template-Parameter. Heißt der Typ der Objekte, die der vector verwalten soll.

    Stillmrkralo schrieb:

    Arbeite ich dann mit dem. Ontainer oder kann ich direkt mit dem inhalt arbeiten?

    Die Frage macht nicht wirklich Sinn, aber ich versuche mal darauf zu antworten. Du arbeitest mit dem Container. Der hat z.B. Methoden wie .push_back(), .size(), .erase(), etc. Eine vollständige Auflistung findest du in einer Referenz.
    http://en.cppreference.com/w/cpp/container/vector
    Trotzdem kannst du natürlich auf einzelne Elemente zugreifen. z.B. über den operator []. v[0] greift auf das erste, v[1] auf das zweite Element etc. zu. Du darfst natürlich nur bis maximal v[v.size() - 1] zugreifen. Wie bei einem Array halt.



  • Kralo9still schrieb:

    Bzw. Hab ich mit vector einen dynamischen array der mitwächst?

    Hab ich dOch so schon richtig verstanden.
    Aber ich hab dann keine möglichkeit mehr, mit den "richtigen" objektnamen zu arbeiten? Sprich mc, wie es in meinem code am anfang stand.



  • Dynamisch angeforderter Speicher hat keinen Bezeichner. Dein mc war auch nur ein Pointer.



  • Ja schon. Aber es wäre dennoch einfacher die objekte hinterher direkt mit ihrem namen zu referenzieren, weil jedes sich von allen andren unterscheidet. (zum besseren verständnis: die objekte sind buttons in meinem spiel die jeweils andere positionen und texturen haben. Somit is es einfacher das objekt startgamebutton zu referenzieren als v[12]) Gibts dafür eine geschicktere lösung. Wie siehts aus mit enum?



  • Macht es denn überhaupt Sinn, die Buttons in einem Vektor zu speichern?
    Evtl. ist es besser, pro Buttonart eine eigene Klasse zu verwenden?



  • Ich hab eine allgemeine klasse die sich auf buttons spezialisiert. Und für jeden button will ich ein objekt anlegen. Ich mach da doch lieber 100 objekte die fast gleich sind, bis auf position und textur, anstatt 100 klassen. Ich nehme schliesslich auch 1 auto und kann mit dem in 100 verschiedene städte fahren und hab nicht 100 autos für 100 städte, oder?



  • Ok, wenn Du pro Button ein Objekt erzeugen willst, kannst Du dem jeweiligen Objekt dann auch die gewünschte Bezeichnung geben.

    Der Zugriff auf einen Vektor könnte dann z.B. mit

    cout<<Startbutton.v[12];
    

    erfolgen.



  • Mir ist da grad eine idee gekommen wie ich das lösen könnte. Was haltet ihr davon:

    Std::vector<MyClass> load(){
    
    std::vector<MyClass> v;
    
    MyClass* mc = new MyClass;
    //einstellungen vornehmen für mc
    mc->setName("startgame");
    v.push_back(mc);
    
    MyClass* mc2 = new MyClass;
    //einstellungen vornehmen für mc2
    mc->setName("settings");
    v.push_back(mc2);
    
    return v;
    } 
    
    Int main(){
    
    std::vector v = load();
    
    For(int i = 0; i < v.size() - 1; i++){
    if(v[i].getName() == "settings"){
    //settings wurde gefunden hurra
    //arbeite mit diesem
    }
    
    return 0;
    }
    

    Man kann diese suchschleife in eine funktion packen, der man den suchstring und den vector übergibt und die dann die arraynummer zurückgibt.

    Etwa so:

    Int getArrayNum(std::string, std::vector){...}
    


  • Nicht so viel, da

    SeppJ schrieb:

    Besser: Gar nicht so etwas programmieren. Ein mit new erstelltes Objekt über einen rohen Zeiger aus einer Funktion herausgeben ist äußerst unsauber und provoziert Fehler en masse.

    Wenn ich den Code richtig verstehe, ist die Anwendung von new doch gar nicht
    notwendig.
    Du kannst ein Objekt doch einfach so erzeugen, also z.B.:

    myclass mc;
    myclass mc2;
    

    Hinzu kommmt, wenn ich das richtig verstehe, ist der von Dir erzeugte Vektor nur
    innerhalb der Funktion gültig. Du gibst den Vektor zwar mittels return zurück, das ist aber für das weitere Arbeiten eher nicht so gut, da der Vektor dann nur noch temporär gültig ist.

    Besser wäre vemutlich den Vektor ausserhalb der Funktion,aber innerhalb der Klasse zu erzeugen.
    Dann kannst Du eine Funktion schreiben, den Vektor als Referenz übergeben und dann innerhalb der Funktion damit arbeiten.



  • Ich gebe aber doch keinen rohen zeiger, sondern den Container zurück



  • Du hast den vector überhaupt nicht verstanden. Er verwaltet den Speicher für seine Objekte. Das kompiliert so doch nicht mal. Du pushst Objekte selbst in den vector, keine Pointer.



  • Also erstelle ich die obiekte kurz gefasst so

    MyClass mc;
    ...
    v.push_back(mc);
    

    Und die objekte kann ich dann immernoch, mit arraynummer, erreichen?
    Behandle ich dann v[] als objekt oder pointer. Wahrscheinlich als poitner wenn er den speicher selbst anlegt, oder?

    Dann muss ich drauf so referenzieren:

    v[getArrayNum("schiessmichtotichversteheswohlimmernochnicht", v)]->setName("oderdoch?");
    


  • cooky451 schrieb:

    Du hast den vector überhaupt nicht verstanden. Er verwaltet den Speicher für seine Objekte. Das kompiliert so doch nicht mal. Du pushst Objekte selbst in den vector, keine Pointer.

    Den vector nicht. Aber ich kenne templates. Vector gehört doch nicht zu den grundlagen. Zumindest steht davon nix in meinem buch. Also vom std::vector



  • Ne, als Objekt. v[i] ist genau der Typ, den du in den eckigen Klammern angegeben hast. In deinem Beispiel wird übrigens kopiert, was bei Buttons wenig Sinn macht. Die könnte man aber movable machen.
    Nur scheinen dir weder Konstruktoren, noch Destruktoren oder Kopierkonstruktor, Zuweisungsoperator etc. etwas zu sagen. Nur mal als Tipp: Du solltest hier dringend die Grundlagen lernen. Man kann sich durch rumprobieren zwar so durchwurschteln bis man etwas hat was irgendwie so läuft, aber das dauert doch wesentlich länger und zahlt sich sicher nicht aus. 😉
    C++ Primer ist die übliche Buchempfehlung.



  • Könnte mir nicht einfach jmd sagen, was konkret an meiner idee falsch ist oder sie direkt dazu ums hreiben? Normal versteh ich doch alles wenn mir was erklärt wird, zumindest wenn es sich auf die grundlagen bezieht... 😞



  • kralo9 schrieb:

    cooky451 schrieb:

    Du hast den vector überhaupt nicht verstanden. Er verwaltet den Speicher für seine Objekte. Das kompiliert so doch nicht mal. Du pushst Objekte selbst in den vector, keine Pointer.

    Den vector nicht. Aber ich kenne templates. Vector gehört doch nicht zu den grundlagen. Zumindest steht davon nix in meinem buch. Also vom std::vector

    Vektoren sind unheimlich wichtig, da sie sehr oft vorkommen.
    Und gehören daher definitiv zu den Grundlagen.

    Zunächst einmal geht es ja nur um das einfache Anwenden, nicht um das detaillierte Verständnis eines Klassentemplates (was Vektoren ja sind).



  • Zunächst einmal geht es ja nur um das einfache Anwenden, nicht um das detaillierte Verständnis eines Klassentemplates (was Vektoren ja sind).

    Und wie würde das dann bei meiner Idee aussehen?! 😃



  • kralo9 schrieb:

    Ich gebe aber doch keinen rohen zeiger, sondern den Container zurück

    Ja, und soweit ich das weiß, wird dann der komplette Vektor übergeben, anstatt nur eine Referenz oder ein Zeiger darauf. Bei größeren Vektoren kann das durchaus
    spürbare Geschwindigkeitsnachteile zur Folge haben.
    Hinzu kommt, der Vektor als Rückgabewert ist im Prinzip nur noch temporär gültig.
    Weiteres Arbeiten damit dürfte ziemlich umständlich, wenn nicht sogar unmöglich sein.



  • redrew99 schrieb:

    Ja, und soweit ich das weiß, wird dann der komplette Vektor übergeben, anstatt nur eine Referenz oder ein Zeiger darauf. Bei größeren Vektoren kann das durchaus
    spürbare Geschwindigkeitsnachteile zur Folge haben.

    Falsch, siehe RValue-Referenzen und RVO.

    redrew99 schrieb:

    Hinzu kommt, der Vektor als Rückgabewert ist im Prinzip nur noch temporär gültig.
    Weiteres Arbeiten damit dürfte ziemlich umständlich, wenn nicht sogar unmöglich sein.

    Quatsch.

    @kralo9

    #include <iostream>
    #include <string>
    #include <vector>
    
    struct mystruct
    {
      std::string name;
      mystruct(std::string name)
        : name(std::move(name))
      {}
    };
    
    std::vector<mystruct> gimme_more_objects()
    {
      std::vector<mystruct> v;
      v.push_back(mystruct("Hallo"));
      v.push_back(mystruct("Welt!"));
      return v;
    }
    
    int main()
    {
      std::vector<mystruct> v = gimme_more_objects();
      for (std::size_t i = 0; i != v.size(); ++i)
        std::cout << v[i].name << '\n';
    }
    


  • Auf die geschwindigkeit kommt es mir hier nicht an, da die texturen nur bei programmstart geladen werden. Also die funktion wird nur einmal aufgerufen.
    Und ganz nebenbei: wenn das laden ewig dauert wirkt mein spiel wie eins der professionell enteickelten wie die von ea und so :D:D


Anmelden zum Antworten