[Solved]Standard Container mit eigenen Objekten



  • Guten Tag,
    ich komme eigentlich aus dem Java Bereich und wollte mich an C++ heranwagen....

    folgendes Problem :
    ich habe eine Klasse 'Prod' erstellt und wollte in der main instanziieren und dieses Objekt dann in einem std::vector (oder auch list oder sonst was) reinhauen.

    ich hatte es bisher nur mit den standardtypen int,double,char etc getan aber irgendwie will das bei eigenen Objekten nicht klappen ... bei der Ausgabe kommt dann nur garbage raus, als ob sich der vector verzeigert oder so.

    (frage nebenbei: macht vector nur einen Zeiger auf das objekt oder erstellt er intern eine kopie?)
    main.cpp : (nicht stören lassen von der for schleife, bin noch c++ anfänger und kenn noch nicht alle functionalitäten, aber das mit dem objekt ist mir erstmal wichtiger)

    char c [100];
        vector<Prod> qu;
    
        cout << "Bitte geben Sie eine Produktion der Form A -> BC oder A -> a ein.\n";
    
        char word [100];
        while (cin >> word && word[0] !='0') {
            for (int i=0;i<sizeof(word)-3;i++) {
                c[i] = word[i+3];
            }
            qu.push_back(Prod(word[0],c));
        }
    
        cout<< qu.front().getSymbol();
    

    Prod.h

    class Prod {
    public:
        Prod();
        Prod(char s, char c []);
        Prod(const Prod& orig);
        virtual ~Prod();
        char getFront();
        char getSymbol();
    private:
         char symbol;
         char front;
    };
    

    Prod.cpp

    Prod::Prod(char s , char c []) {
        this->symbol = s;
        this->front = c[0];
    }
    
    char Prod::getFront() {
        return this->front;
    }
    
    char Prod::getSymbol() {
        return this->symbol;
    }
    

    Also ich habs eigentlich noch ziemlich simple gehalten... aber irgendwie will mein Beispiel nicht funktionieren

    ich benutz netbeans c++ plattform mit msys compiler

    vielen Dank schonmal im Vorraus
    Terry



  • Hi,
    1.) std::vector erstellt intern eine Kopie.
    2.) Der Fehler könnte hier liegen:

    qu.push_back(Prod(word[0],c));
    

    Da erstellst du zwar ganz regulär über deinen Konstruktor dein Objekt, aber anschließen wird dieses temporäre Objekt dann in dein vector kopiert, ergo wird dann dein Copy-Constructor aufgerufen, den du uns auch noch zeigen musst 🙂



  • Entsteht der "Garbage" vielleicht, weil du glaubst, in Prod::front sei ein String gespeichert?

    Grundsätzlich solltest du std::string statt char-Array verwenden, um Strings zu speichern.



  • - war leider falsch -



  • ipsec schrieb:

    ...

    😉



  • erstmal vielen Dank

    @kasf

    Da erstellst du zwar ganz regulär über deinen Konstruktor dein Objekt, aber anschließen wird dieses temporäre Objekt dann in dein vector kopiert, ergo wird dann dein Copy-Constructor aufgerufen, den du uns auch noch zeigen musst 🙂

    aha, dass wusste ich nicht, da müsste ich mich kurz belesen (was ich auch sofort tun werde, trotzdem wäre ein beispiel schön 🙂 )

    @ rest :
    das mit string werd ich gleich ausprobieren, aber ich habe es gerade mit nur chars ausprobiert, was auch nicht funktioniert : Beispiel Ein-/Ausgabe
    Eingabe
    B->aC
    0

    Augabe
    Ä

    mfG
    Terry



  • Das Programm (mit deinem geposteten Code)

    #include <vector>
    #include <iostream>
    
    using namespace std;
    
    class Prod {
    public:
        Prod(char s, char c []);
        char getFront();
        char getSymbol();
    private:
         char symbol;
         char front;
    };
    
    Prod::Prod(char s , char c []) {
        this->symbol = s;
        this->front = c[0];
    }
    
    char Prod::getFront() {
        return this->front;
    }
    
    char Prod::getSymbol() {
        return this->symbol;
    }
    
    int main()
    {
    char c [100];
        vector<Prod> qu;
    
        cout << "Bitte geben Sie eine Produktion der Form A -> BC oder A -> a ein.\n
    ";
    
        char word [100];
        while (cin >> word && word[0] !='0') {
            for (int i=0;i<sizeof(word)-3;i++) {
                c[i] = word[i+3];
            }
            qu.push_back(Prod(word[0],c));
        }
    
        cout<< qu.front().getSymbol();
    }
    

    macht das

    Bitte geben Sie eine Produktion der Form A -> BC oder A -> a ein.
    B->aC
    0
    B

    Wenn bei dir etwas anderes herauskommt liegt es wohl an dem Code, den du nicht gepostet hast.



  • hmmm ich hab das ungute gefühl das es nicht am code liegt... ich hatte eignetlich alles relevante kopiert... hier nochmal alles :
    Prod.h

    /* 
     * File:   Prod.h
     * Author: Terry
     *
     * Created on 20. Juni 2011, 20:49
     */
    
    #ifndef PROD_H
    #define	PROD_H
    
    #include<queue>
    #include<string>
    class Prod {
    public:
        Prod();
        Prod(char s, char c);
        Prod(const Prod& orig);
        virtual ~Prod();
        char getFront();
        char getSymbol();
    private:
         char symbol;
         char front;
    };
    
    #endif	/* PROD_H */
    

    Prod.cpp

    /* 
     * File:   Prod.cpp
     * Author: Terry
     * 
     * Created on 20. Juni 2011, 20:49
     */
    
    #include "Prod.h"
    #include <iostream>
    Prod::Prod() {
    }
    
    Prod::Prod(char s , char c ) {
        this->symbol = s;
        this->front = c;
    }
    
    Prod::Prod(const Prod& orig) {
     // hier müsste diese Copsache rein oder?
     // hatte versucht this->symbol = orig.getSymbol();   
     // und äquivalent für front aber das wollte mir netbeans nicht abkaufen
     // was ist der fehler ? 
    }
    
    char Prod::getFront() {
        return this->front;
    }
    
    char Prod::getSymbol() {
        return this->symbol;
    }
    
    Prod::~Prod() {
    }
    

    und die main.cpp

    /* 
     * File:   main.cpp
     * Author: Terry
     *
     * Created on 20. Juni 2011, 23:22
     */
    
    #include <iostream>
    #include "Prod.h"
    #include <vector>
    #include <string>
    using namespace std;
    
    /*
     * 
     */
    int main(int argc, char** argv) {
        char c [100];
        vector<Prod> qu;
    
        cout << "Bitte geben Sie eine Produktion der Form A -> BC oder A -> a ein.\n";
    
        char word [100];
        while (cin >> word && word[0] !='0') {
            for (int i=0;i<sizeof(word)-3;i++) {
                c[i] = word[i+3];
            }
            qu.push_back((Prod)Prod(word[0],c[0]));
        }
    
        cout<< qu.front().getSymbol();
        return 0;
    }
    

    so das ist 100% des Codes der bei mir nicht funzt 😞

    mfG
    Terry

    EDIT :
    der copy construktor scheints gewesen zu sein....ich muss aber kurz weiter testen



  • Ein Copy-Constructor wird aufgerufen, wenn ein Objekt vom Typ A in ein anderes Objekt vom Typ A kopiert wird. Und dies geschieht in deinem Falle beim push_back, dort wird dein temporäres Objekt "Prod(word[0],c)" in ein Prod-Objekt vom vector kopiert.

    Ein Copy-Constructor sieht so aus:

    ClassName (const ClassName& obj);
    

    Also in deinem Falle ist das:

    Prod(const Prod& orig);
    

    Wenn du ihn leer implementiert haben solltest, also:

    Prod::Prod(const Prod& orig)
    { }
    

    dann ist das dein Fehler, da du da die Elemente aus orig in deinen eigenen Container kopieren musst, also:

    Prod::Prod(const Prod& orig)
    { 
        front = orig.front;
        symbol = orig.symbol;
    }
    

    Da dies aber nur PODs sind, also einfach Datentypen, brauchst du den Copy-Constructor (CC) nicht zu implementieren. Das übernimmt dein Compiler für dich. Würdest du aber dynamische Resources (zB Zeiger) in der Klasse haben, müsstest du einen CC implementieren. Ansonsten würde der vom Compiler erzeugte CC den Zeiger einfach kopieren und beide Objekte hätten einen Zeiger auf das selbe Objekt, was nicht gewünscht ist. In diesem Falle müsstest du den CC selbst implementieren und eine Kopie des hinterm Zeiger liegenden Objekts für das aktuelle Objekt selbst erstellen.

    Aber vergiss einfach was ich gesagt habe und benutz einfach die schönen Standardcontaier, wie std::string und std::vector und du brauchst den Zeiger-Quatsch nicht 🙂



  • danke KasF hab es nach 2 anläufen doch (sogar selbst) hinbekommen 🙂
    es scheint auch zu funktionieren... 🙂 (vorerst) 😉

    trotzdem danke nochmal das du es nochmal aufgeschrieben hast 🙂
    vielen Dank! auch an die anderen
    liebe Grüße
    Terry

    aso und der nachsatz das der compiler das übernimmt, ich nutze msys ...der scheint es nicht zu übernehmen 😞


Anmelden zum Antworten