Kopierkonstruktor



  • Hallo,

    kann mir einer sagen wie der Kopierkonstruktor zu folgendem Konstruktor aussehen müsste?

    GelochtePlatte(double laengePlatte, double breitePlatte, int maxLoecher):
        MetallPlatte(laengePlatte, breitePlatte)
        {
            anzahlLoecher = 0;
            this->maxLoecher = maxLoecher;
            loch = new MetallPlatte* [maxLoecher];  
    
            for (int i=0; i < maxLoecher; i++ ) 
            { 
                loch[i] = NULL; 
            }
    
            lochBreite = 1/(2*maxLoecher) * getBreite();
            lochLaenge = 1/(2*maxLoecher) * getLaenge();
        }
    


  • Das ist die falsche Frage :p

    Frage müßte lauten: Wie sieht der Kopierkonstruktor zur folgenden Klasse aus?

    Ohne zu wissen welche Membervariablen deine Klasse hat und wie diese behandelt werden lässt sich deine Frage nicht wirklich beantworten.



  • Hallo,

    Die Klasse GelochtePlatte ist von der Klasse MetallPlatte abgeleitet. Die Klasse MetallPlatte hat die Attribute laenge und breite. Die Klasse GelochtePlatte hat zusätzlich die Attribute:

    int anzahlLoecher;
    int maxAnzahlLoecher;
    double lochLaenge;
    double lochBreite;
    MetallPlatte** loch;



  • Die Klasse GelochtePlatte ist von der Klasse MetallPlatte abgeleitet. Die Klasse MetallPlatte hat die Attribute laenge und breite. Die Klasse GelochtePlatte hat zusätzlich die Attribute:

    Die int und double-Werte kannst du einfach zuweisen. Bei Loch wirst du nicht darum herum kommen ein neues Loch mit dessen kopierkonstruktor anzulegen.

    (Unter der Voraussetzung, dass die GelochtePlatte nicht nur eine Referenz auf das Loch hält sondern dieses auch löscht. Was mich ein bißchen irritiert ist, dass das Loch ein Pointer auf einen Pointer ist. Dies spricht dafür, dass du dir mal angucken solltest was dort passiert. Könnte sein, dass dein Loch in Wirklichkeit Löcher sind oder das Loch in einer separaten Struktur gehalten wird.)



  • Im folgenden hab ich mal den Quellcode vom Konstruktor und Kopierkonstruktor hingeschrieben. Mein Problem liegt nun in der Zeile MetallPlatte(10, 20) des Kopierkonstruktors. Wenn ich die Argumente wie hier geschehen auf 10 und 20 setze kompiliert das Programm. Wenn ich aber hingehe und diese Zeile durch
    MetallPlatte(rhs.laengePlatte, rhs.breitePlatte) ersetze macht das Compilieren Probleme. Kann mir einer sagen warum das nicht so geht und wie ich das richtig umsetzen kann. Achso es wäre sehr nett wenn ihr mich auf weitere Fehler in meinem Kopierkonstruktor aufmerksam machen könntet.

    GelochtePlatte(double laengePlatte, double breitePlatte, int maxAnzahlLoecher):
    MetallPlatte(laengePlatte, breitePlatte)
    {
        anzahlLoecher = 0;
        this->maxAnzahlLoecher = maxAnzahlLoecher;
        loch = new MetallPlatte* [maxAnzahlLoecher];  
        for (int i=0; i < maxAnzahlLoecher; i++ ) 
        { 
            loch[i] = NULL; 
        } 
        lochBreite = 1/(2*maxAnzahlLoecher) * getBreite();
        lochLaenge = 1/(2*maxAnzahlLoecher) * getLaenge();
    } 
    
    GelochtePlatte(const GelochtePlatte& rhs):
    MetallPlatte(10, 20)                      
    {
        anzahlLoecher = rhs.anzahlLoecher;
        maxAnzahlLoecher = rhs.maxAnzahlLoecher;
        loch = new MetallPlatte* [maxAnzahlLoecher];  
        for (int i=0; i < maxAnzahlLoecher; i++ ) 
        { 
            loch[i] = rhs.loch[i]; 
        } 
        lochBreite = rhs.lochBreite;
        lochLaenge = rhs.lochBreite;
    }
    


  • da du die Fehlermeldung des Compilers nicht mit angegeben hast, kann ich nur vermutungen anstellen.
    Ich vermute mal, dass laengePlatte und breitePlatte private Elemente von MetallPlatte sind. Wenn das der Fall ist, dann bedeutet das, dass NUR MetallPLatte selbst darauf zugreifen kann, nichtmal KindKlassen haben darauf Zugriff.
    Versuchs mal, indem du den CopyCtor von MetallPlatte mit rhs als argument aufrufst:

    GelochtePlatte(const GelochtePlatte& rhs)
      : MetallPlatte(rhs), anzahlLoecher(rhs.anzahlLoecher),
      maxAnzahlLoecher(rhs.maxAnzahlLoecher), loch(new MetallPlatte* [rhs.maxAnzahlLoecher], 
      lochBreite(rhs.lochBreite), lochLaenge(rhs.lochLaenge)
    
      {
      for (int i=0; i < maxAnzahlLoecher; i++ )
        {
        loch[i] = rhs.loch[i];
        }
      }
    

    der Copy-Ctor von MetallPlatte nimmt ja als Argument eine Referenz auf MetallPlatte an, und dank Polymorphie ist eine Referenz auf eine Kindklasse (GelochtePlatte& rhs) gleichzeitig eine Referenz auf die Basisklasse.

    Zwei Dinge noch:

    1. Habe ich so ziemlich alle einfache Zuweisungen in die Initialisierungsliste gepackt. Das hilft später, zu sehen, wo wirklich was anderes passiert ist als mehr oder weniger stumpfes kopieren (weniger stumpf bei Zeigerkopien).
      Man muss aber aufpassen, dass man die Initialisierungsliste IMMER in der gleichen Reihenfolge schreibt wie die Memberdeklaration, da der Compiler sie auch immer in der Reihenfolge ausführt. (Klar, denn die Member liegen im Speicher in der Reihenfolge wie sie deklariert wurden, und der Compiler soll bei der Initialisierung nicht unnötig hin und herspringen)
      Das würde aber folgendes bedeuten: Wenn das Member "loch" vor dem Member "maxAnzahlLoecher" deklariert wird und du in der initliste hinschreibst "loch(new MetallPlatte* [maxAnzahlLoecher])", dann ist ,axAnzahlLoecher noch nicht initialisiert und daher kann und wird das Array eine Länge haben man bestenfalls als willkürlich bezeichnen kann.
    2. Ist mir aufgefallen, dass du in dem Array zwar brav die Zeiger auf die Löcher kopierst, nicht aber die Löcher selbst. Das bedeutet: wenn du die Löcher der alten Platte änderst, werden die Löcher der neuen mitgeändert, weil es ein und dieselben sind. Falls du die auch kopiert haben willst, müsste in die for-Schleife etwa folgendes:
    loch[i] = new MetallPlatte(*(rhs.loch[i]))
    

    Und ich nehme mal an dass du das willst, denn da du das Array im Konstruktor mit new[] erstellst, solltest du es im Destruktor auch wieder mit delete[] löschen. Und vorher bitte die Löscher, auf die die Zeiger im Array verweisen, falls du nicht noch an völlig anderer Stelle die Löcher aufbewahrst. Das heißt aber dass du der neuen GelochtePlatte die Löcher unterm Ar** weglöschst, wenn die alte zerstört wird...



  • Hallo,

    vielen Dank für die super Antwort 🙂


Anmelden zum Antworten