problem bei objekterzeugung zur Laufzeit - Zeichenprogramm



  • ok, habe ich auch vertanden 🙂 .

    allerdings ist beim test der obigen Methode ein Fehler bei der Kompilierung aufgetaucht:

    Beispiel:

    class Kreis
    {
      public:
      int radius;
      //Konstruktor:
      Kreis(int p_radius)
      {
        radius=p_radius;
      }
      //Beispielmethode:
      void ausmalen()
      {
        //Code zum Ausmalen
      }
    };
    
    Kreis* k1=NULL;
    
    int main()
    {
      //...
      k1=new Kreis(radius);//klappt soweit fehlerfrei
      //nur die folgende zeile mag der Compiler nicht:
      k1.ausmalen();
    }
    

    bei der genannten Zeile sagt der Compiler: error C2228: Links von ".ausmalen" muss sich eine Klasse/Struktur/Union befinden."; k1 ist aber doch Objekt der Klasse Kreis! was ist denn falsch?

    und noch ne ganz kleine Frage: ein Destruktor für die Klasse Kreis ist hier nicht unbedingt nötig, oder?

    mfg,
    andi01.



  • Nein. k1 ist vom Typ: "Zeiger auf Kreis". Das ist völliger Unterschied. 😉

    Aber die Handhabung ist denkbar einfach.

    k1->ausmalen(); // bedeutet: (*k1).ausmalen();
    

    Der -> Operator dereferenziert dir den Zeiger und dann hast du etwas vom Typ "Kreis" und wendet den . Operator drauf an. (Achtung: der -> Operator kann überladen werden und somit theoretisch eine völlig andere Bedeutung haben, als die ausgeschriebene Variante; ist aber eher unüblich, ausser bei Smart Pointer).



  • Und vergiss das delete nicht, wenn du mit new Speicher anforderst!



  • wird der speicher nicht nach programmende automatisch freigegeben? naja, offensichtlich nicht 😃

    ist es dann nicht doch soinnvoll einen destruktor zu schreiben?

    mfg,
    andi01.



  • andi01 schrieb:

    wird der speicher nicht nach programmende automatisch freigegeben? naja, offensichtlich nicht 😃

    Wahrscheinlich schon, aber es ist 1. nicht garantiert, und 2. ist es schlechter Stil und führt nur dazu, dass die Regel an anderen Orten auch nicht beachtet wird. Merk dir einfach, dass zu jedem new ein delete und zu jedem new[] ein delete[] gehört (von Dingen wie Smart-Pointern mal abgesehen).

    andi01 schrieb:

    ist es dann nicht doch soinnvoll einen destruktor zu schreiben?

    Nein, das hat damit nichts zu tun. In der Klasse selbst forderst du nirgends Speicher vom Freestore an, der standardgenerierte Destruktor tut das Richtige.



  • andi01 schrieb:

    wird der speicher nicht nach programmende automatisch freigegeben? naja, offensichtlich nicht 😃

    ist es dann nicht doch soinnvoll einen destruktor zu schreiben?

    mfg,
    andi01.

    Doch wahrscheinlich schon, aber das ist Sache des Betriebssystems, ob das gemacht wird. Also verlass dich nicht drauf!

    Destruktoren machen durchaus Sinn, aber in dem Falle hier bringt dir das nix, weil delete this keine gute Idee ist. (überleg dir dazu, was so aufgerufen wird, wenn ein Objekt zerstört wird. ;))

    Du kannst eine Klasse schreiben, die dir das Obejkt mit new erzeugt und dann im Destruktor das löschen vornimmt. Das ist eine gute Idee und nennt sicht dann Smart Pointer. (google danach, für weiteres).



  • ok, so weit habe ich das jetzt auch verstanden 🙂

    (um keinen neuen thread eröffnen zu müssen die letzte kleine frage bezüglich des Zeichenprogramms auch noch schnell hier 😃 )

    ist es auch möglich den Benutzer zB den Namen eines objekts eingeben zu lassen und das dann zu erzeugen?

    ich dachte mir das etwa so:

    class Kreis
    {
        public:
        int radius;
    };
    
    int main()
    {
        cout<<"Geben Sie den Namen des zu erzeugenden Objekts ein!\n";
        string name;
        cin>>name;
        //Kreis mit eingegebenem Namen erzeugen, ka wie^^(z.B. Kreis name =new Kreis?) 
    }
    

    Hintergrund ist dass es das programm erheblich vereinfachen müsste da ich die ganzen objektnamen nicht selbst vergeben muss und auch nicht bei jedem Objekterstellen den passenden Namen(zB k1/k2/...) suchen müsste^^

    geht das irgendwie?

    mfg,
    andi01.



  • Das grundlegende Prinzip, dass du suchst sind natürlich Arrays. Allerdings bietet sich da wahrscheinlich ein Standardbibliothek Container eher an.

    vector:
    http://www.cplusplus.com/reference/stl/vector/

    oder aber eben, wenn der Name wirklich wichtig ist:

    map:
    http://www.cplusplus.com/reference/stl/map/



  • ich weiß, ich könnte das schon mit einer art arrays lösen. das problem ist das macht den code recht unübersichtlich(in Klassen sind ja zB auch zugehörige methoden/attribute usw. auf den ersten blick erkennbar, das macht den code besser lesbar^^)

    Außerdem würde das doch unglaublich speicher verbrauchen wenn man alle parameter in multidimensionale arrays packt:

    //kreis[name][radius][x_mittelpunkt][y_mittelpunkt][füllfarbe]:
    string kreis [100][100][100][100];
    

    wenn man das mit allen nötigen parameter für alle klassen macht braucht das einiges an speicherplatz^^

    deshalb wollte ih das ganze eigentlich mit Klassen und Objekten lösen, aber das mit dem Namen eingeben funktioniert da wohl definitiv nicht, oder?

    mfg,
    andi01.



  • andi01 schrieb:

    deshalb wollte ih das ganze eigentlich mit Klassen und Objekten lösen, aber das mit dem Namen eingeben funktioniert da wohl definitiv nicht, oder?

    Äh, doch.

    Nicht ohne Grund hat dich drakon auf std::map hingewiesen. Als Ergänzung hilft dir vielleicht dieser Artikel.



  • d.h. wenn das obere Codebeispiel funktionieren soll müsste ich alle Attribute der einzelnen vorherigen Objekte in solchen maps speichern?

    Wenn nicht wie soll das denn dann funktionieren?hätte vielleicht mal jemand in kleines codebeispiel(nur so lang wie oben, das erstellen eines objekts mit dem eingegebenen Namen würde ja schon reichen 🙂 )?

    mfg,
    andi01.



  • andi01 schrieb:

    Außerdem würde das doch unglaublich speicher verbrauchen wenn man alle parameter in multidimensionale arrays packt:

    //kreis[name][radius][x_mittelpunkt][y_mittelpunkt][füllfarbe]:
    string kreis [100][100][100][100];
    

    wenn man das mit allen nötigen parameter für alle klassen macht braucht das einiges an speicherplatz^^

    ?!
    Für etwas hast du ja eine Klasse, wo du die Parameter drin speichern kannst..

    Im übrigen ist das eh nicht das, was du denkst, dass es ist..
    Da wird ein Array von Arrays von Arrays von Arrays erstellt. 100^4. Viel Spass. 😉



  • solangsam wird das ganz schön kompliziert^^.

    hätte vielleicht mal jemand einen kleinen Codeschnipsel? das erstellen eines objekts mit dem eingegebenen namen würde ja schon reichen^^

    eigentlich nräuchte ich nur ein kleines beispiel wie man den namen eines objekts eingeben kann und dieses dann erstellen.

    mfg,
    andi01.



  • andi01 schrieb:

    Wenn nicht wie soll das denn dann funktionieren?hätte vielleicht mal jemand in kleines codebeispiel(nur so lang wie oben, das erstellen eines objekts mit dem eingegebenen Namen würde ja schon reichen 🙂 )?

    Objektorientiert heisst eben, dass du gemeinsame Attribute zu einem Objekt zusammenpackst. Dann brauchst du auch keine vierdimensionalen Arrays.

    class Kreis
    {
        public:
            // Konstruktoren etc.
    
        private:
            float   radius;
            Farbe   fuellfarbe; // Farbe ist eine andere Klasse von dir
            Vector2 mittelpunkt; // Vector2 ist eine andere Klasse mit 2 floats
    };
    
    std::map<std::string, Kreis> kreise;
    // wie du nun Kreise einfügst, findest du in den Links zu std::map.
    // bitte diese LESEN!
    


  • ok, dass heißt ich kann die klassen behalten. die eingegebenen objektnamen müsste ich dannin irgendeinen container (zB map) packen. soweit klar.

    nur wie man dann aus der map die objekte konstruiert habe ich noch nicht gefunden. ich schaue mir die links nochmal genauer an^^

    mfg,
    andi01.



  • hm irgendiwe ist mir noch nicht ganz klar wie ich aus der namensliste (zB map) die Objekte erstellen soll. ein kleines Beispiel wäre nicht schlecht 😃

    danke,
    andi01.



  • In der map sind Objekte drin. Die werden beim einfügen erstellt.

    Einfügen kannst du z.B mit der Memberfunktion insert oder gleich mit dem [] Operator:

    http://www.cplusplus.com/reference/stl/map/operator[]/



  • ok, habs kapiert 🙂 .

    danke allen für die hilfe,
    andi01.


Anmelden zum Antworten