Objekte auf dem Heap -> Methodenzugriff?



  • Das sind dann 10 Objekte von dem Typ, ja.



  • Die Antwort war ja jetzt denkbar knapp gehalten 😉
    Wenn ich allerdings versuche, in meiner Spielverwaltung ein Kartenarray zu erzeugen, dann spuckt mir der Compiler den Fehler aus, dass kein geeigneter Standardkonstruktor verfügbar ist.

    Grüße,
    Neras



  • Dann stellst du den halt zur Verfügung. (und machst die Initialisierungswerte halt nachher rein). Oder benutzt gleich einen Container, à la std::vector, std::tr1::array oder boost::array. Die kannst du auch mit einem selbst definiertem Konstruktor benutzen.

    Das Problem ist halt, dass du einen riesen Umweg machen willst, der überhaupt nicht nötig ist und daher verstehe ich nicht ganz, was du willst.



  • Ok, ich habe es jetzt mit dem vector geschafft... ich weiß nicht, warum es gestern nicht geklappt hat... vielleicht wars einfach zu spät xD Es sieht jetzt so aus:

    int y = 0;
    	while(y < 10)
    	{
    		Karte *koenigKarte1 = karteErzeugen(stapelAuswahl);
    		karten.push_back(koenigKarte1);
    		stapelAuswahl++;
    		y++;
    	}
    

    Dann übertrage ich den Vector aus der Kartenfabrik in die Spielverwaltung:

    vector<Karte*> Kartenfabrik::getKarten()
    {
    	return karten;
    }
    
    Kartenfabrik spiel(pStapelAuswahl);
    	spielKarten = spiel.getKarten();
    

    Und dann versuche ich einen Zeiger auf die erste Stelle des Vectors zu erstellen:

    Karte** koenigKarte1;
    [...]
    koenigKarte1 = &spielKarten[0];
    

    Ob das jetzt auf den ersten Blick Sinn ergibt, ist egal, jedoch hat sich da bei mir ein Fehler eingeschlichen, da ich nicht auf das Kartenobjekt zugreifen kann, wenn ich den Zeiger benutze.

    Grüße,
    Neras



  • Wo ist denn jetzt genau noch das Problem?
    Und warum machst du da etwas mit Zeigern? - spielKarten ist ja der std::vector und daher kannst du mit dem auch ganz komfortabel arbeiten.



  • Also ich habe im Endeffekt zehn Zeiger auf zehn verschiedene Kartenobjekte in dem Vector liegen. Jetzt möchte ich nachher wiederum zehn Zeiger auf jeweils einen Zeiger in dem Vector zeigen lassen. Der Sinn dahinter ist der, dass ich diese Zeiger in zehn verschiedene Stacks packen möchte und anstatt 100 Objekte in den zehn Stacks liegen zu haben, lieber Zeiger benutzen möchte. Ich merk schon beim Schreiben, dass das sehr verwirrend klingen mag oO Zusammengefasst möchte ich keine 100 Objekte des Typs Karte erstellen, die ich in meine Stacks packe. Da ich die Kartenobjekte auf dem Heap nicht verändere, sondern nur ihre Werte durch die Zeiger lesen möchte, ist das gefahrlos, denke ich.
    Ich hoffe, du hast verstanden, was ich machen möchte... xD

    Grüße,
    Neras



  • std::vector<const karte*> karten[10];
    
    for (int i = 0; i < 10; i++)
        for (int y = 0; y < 10; y++)
            karten[i][y] = &spielKarten[y];
    

    Wenn spielKarten richtig gefüllt ist, sollte das in etwa so dem entsprechen, was du willst, oder?



  • Wenn ich das von dir versuche, bekomme ich diesen Error:

    error C2440: '=': 'Karte **' kann nicht in 'const Karte *' konvertiert werden
    

    Grüße,
    Neras



  • Ah. Mist. Nimm das & mal weg.



  • Ok, dass macht er nun. Und wie kann ich jetzt auf die Methoden des Objekts zugreifen?

    cout << karten[0];
    

    macht er nicht. Kommt ein "Binärer Operator"-Error. Wenn ich

    karten[0].
    

    mache, kann ich die Methoden des Vectors benutzen, aber ich hab da noch nicht soviel Sinn drin gesehen, sorry ^^°

    Grüße,
    Neras



  • karten ist ja ein vector von std::vector. mit [0] hast du den ersten, dann kannst du mittels karten[0][0] auf die erste Karte im ersten Container zugreifen und da das Zeiger sind mittels des -> Operators.

    karten[0][0]->irgendeine_funktion_von_karte();
    


  • Der Compiler kompiliert das auch und den Ansatz hatte ich vorhin auch schon, aber wenn ich

    cout << karten[0][0]->getName() << endl;
    

    eingebe, komme ich soweit, bis diese Ausgabe bearbeitet wird. Dann bricht das Programm mit einem Error "Expression: vector subscript out of range" ab. Heißt das soviel wie, dass ich etwas lesen will, was nicht vorhanden ist?

    Grüße,
    Neras



  • Genau. Dann hast du Elemente nicht richtig gefüllt. Schau doch mal mit dem Debugger, wo du das genau machst und ob dieser Ausschnittcode auch wirklich nach dem befüllen kommt.



  • Ich habe jetzt festgestellt, dass der Error nicht von dem cout kommt, sondern von der "Einlese-Methode", die du vorhin geschrieben hast. Ich kann dir Code geben, wenn du mir sagst, welche Stellen du brauchst 😉
    Danke an dieser Stelle an dich, dass du mir soweit weiterhilfst 😃

    Grüße,
    Neras



  • Eben, der Error rührt daher, dass du auf den Index [0][0] des std::vector s zugreifst, der aber nicht vorhanden ist. Mindestens einer der verschachtelten Vectors ist leer, was du auch mit size() oder empty() überprüfen kannst.

    Geh zu der Stelle, wo der std::vector initialisiert wird und stelle sicher, dass sich danach Elemente im Container befinden.



  • Ich hab vor die Schleifen eine size Abfrage gestellt und heraus kam, dass der vector "spielKarten" 10 Elemente hat und der vector "karten" 0 Elemente. In den Schleifen sollte der vector "karten" ja dann gefüllt werden. Erscheint mir also richtig, oder? oO Auffällig waren nur die unterschiedlichen schreibweisen der beiden size-Abfragen:

    cout << spielKarten.size() << endl;
    cout << karten->size() << endl;
    

    Grüße,
    Neras



  • Ja, aber bevor der karten -Vector gefüllt ist, darfst du nicht mit dem Indexoperator darauf zugreifen. Mit der Memberfunktion push_back() kannst du allerdings Elemente hinten anhängen.

    Die unterschiedliche Schreibweise mit operator. und operator-> hat damit zu tun, dass die eine Variable ein std::vector und die andere ein std::vector* ist. Kommt halt drauf an, wie sie deklariert wurden



  • std::vector<Karte*> spielKarten;
    std::vector<const Karte*> karten[10];
    
    Kartenfabrik spiel(pStapelAuswahl);
    spielKarten = spiel.getKarten();
    
    cout << spielKarten.size() << endl;
    cout << karten->size() << endl;
    
    for (int i = 0; i < 10; i++)
    for (int y = 0; y < 10; y++)
    karten[i][y] = spielKarten[y];
    
    cout << //Hier will ichdarauf zugreifen
    

    So sieht der Code aus. Ich erstelle zuerst ein neues Objekt der Kartenfabrik und übergebe dann dem vector "spielKarten" mithilfe der Methode des Objektes spiel die Daten aus einem vector des Objekts. Die zwei couts danach sind die Abfragen, wieviel in den beiden vectoren enthalten ist. Dann kommen die Schleifen, die den leeren vector karten füllen sollen. Erst danach greife ich auf diesen zu.
    Also liegt der Fehler an dem

    karten[i][y] = spielKarten[y];
    

    ?
    Grüße,
    Neras



  • Neras schrieb:

    Ich hab vor die Schleifen eine size Abfrage gestellt und heraus kam, dass der vector "spielKarten" 10 Elemente hat und der vector "karten" 0 Elemente. In den Schleifen sollte der vector "karten" ja dann gefüllt werden. Erscheint mir also richtig, oder? oO Auffällig waren nur die unterschiedlichen schreibweisen der beiden size-Abfragen:

    cout << spielKarten.size() << endl;
    cout << karten->size() << endl;
    

    Grüße,
    Neras

    Das ist klar, dass die leer sind. Du hast ja noch nichts befüllt. Das geschieht in der Schleife. Also mach das lieber einmal nach dem befüllen.

    spielKarten gehe ich einmal davon aus, dass das mittlerweile richtig klappt, also musst du nur noch das befüllen richtig machen. Dann klappt das.

    karten ist ja ein Array von vectoren, also müsste der Zugriff so gehen:

    karten[0].size();
    

    Allerdings funktioniert die Version :

    karten->size();
    

    auch, da karten auf das erste Element des Array verweist.

    EDIT:
    Schau mal, wie das ganze aussieht kurz bevor das cout kommt. Also noch bevor der Fehler kommt.



  • Zudem würde ich von sowas abraten:

    std::vector<const Karte*> karten[10];
    

    Willst du wirklich ein Array mit 10 Vectoren vom Typ const Karte* ? Also nicht nur einen Container? Falls ja, würde ich eher std::tr1::array verwenden:

    std::tr1::array<std::vector<const Karte*>, 10> karten;
    

    Geht aber nur mit TR1-Unterstützung (ansonsten boost::array ). Es braucht folgenden Header:

    #include <array>
    

Anmelden zum Antworten