Klassenhierarchie, Vererbung, virtuelle Methoden, Polymorphismus



  • Hallo, ich stecke gerade in einer Klausurvorbereitung und habe noch ein paar Fragen zu den folgenden Themen und es wäre sehr hilfreich wenn ihr mir meine Fragen beantworten würdet.
    Und zwar wenn ich zb eine Klasse Quadrat und Dreieck von einer Klasse Körper ableite wie genau muss ich den Konstruktor verändern in dne jeweiligen Klassen? Falls die Klasse Quadrat die attribute länge und breite hat und die Klasse dreieck länge und höhe und die Klasse Körper alle 3 attribute?

    Falls ich eine dynamische bindung haben will mit einer virtuellen Methode (Polymorphismus) verstehe ich nicht ganz warum der Destruktor auch virtuell sein soll, und der Konstruktor nicht? wie realisiere ich solch eine Implementiereng korrekt?

    Es wäre auch sehr hilfreich wenn mir jemand einen Kopierkonstruktor erklären könnte, ich weiss das er einen "Konstruktor kopiert" und wie das von statten geht, nur ist mir schleierhaft wann ich ihn benutzen soll.

    Vielen Dank schonmal im voraus.

    MfG,
    Wilky



  • Es gibt in C++ keine virtuellen Konstruktoren, der Destruktor muss virtuell sein, damit der richtige aufgerufen wird 😉

    Zu deinen Klassen, deine Klasse Körper sollte nicht alle 3 Attribute haben, die gehören nur in die Subklassen, da sie deren Eigenschaften sind. Hättest du diese Attribute in Körper, so würdest du sagen "Jeder Körper hat eine Länge, eine Breite und eine Höhe", was aber natürlich falsch ist.



  • Falls ich eine virtuelle Methode einbauen möchte, worauf muss ich dabei ganz genau achten?

    Und abstrakte Klassen kann man nicht instanziieren, was genau ist damit gemeint?

    Danke schonmal im voraus.



  • class Koerper
    {
    public:
      // Eine rein virtuelle Methode.
      // Wir legen hier eine Schnittstelle fest, mit der man
      // für (const) Koerper die Fläche bestimmen kann. Die Berechnung
      // ist für jeden Körper anders, daher gibts hier keine 
      // Implementierung. Die Methode ist const, da jeder Körper seine
      // Fläche berechnen können soll, auch wenn er konstant ist.
      // Da diese Methode keine Implementierung hat, kann ich keine Instanz
      // von Koerper anlegen.
      virtual double Flaeche() const = 0;
    
      // Ein virtueller Destruktor
      virtual ~Koerper(){}
    };
    
    class Dreieck : public Koerper  // häm.. ein Dreieck ist eni Körper? naja von mir aus
    {
    public:
      Dreieck(double laenge, double hoehe);
      // Hier implementiert Dreieck die Schnittstelle Flaeche.
      double Flaeche()
      {
         // grundseite x hoehe / 2;
      }
    };
    
    void PrintFlaeche(const Koerper& k)
    {
      std::cout << k.Flaeche();
    }
    
    int main()
    {
     // Koerper k;  // das geht nicht. Koerper ist abstrakt.
      Dreieck d(3.14, 1.0);  // das geht :)
      PrintFlaeche(d);  // das geht
      PrintFlaeche(Dreieck(42.314, 0.1));  // das geht auch
    
      Koerper * k = new Dreieck(1.0, 1.0);
      PrintFlaeche(*k);
      delete k;  // Ruft den Destruktor von Dreieck auf!
                 // weil wir einen virtuellen Destruktor haben
                 // In diesem Bsp. egal, weil es nirgendwo etwas aufzuräumen gibt
    
      return 0;
    }
    

    Virtuelle Destruktoren und Kopierkonstruktoren werden interessanter, wenn es in der Klasse dynamisch erzeugte Elemente gibt.

    class Dreiecksimplementierung;  // Irgendwo definiert
    class KompliziertesDreieck : public Koerper
    {
    public:
      KompliziertesDreieck() : impl(new Dreiecksimplementierung) {}
    
      // Kopierkonstruktor
      KompliziertesDreieck(const KompliziertesDreieck& other) :
        impl(new Dreiecksimplementierung(other.impl))
      {}
    
      ~KompliziertesDreieck()
      {
         // zum Glück ist ~Koerper virtuell
         delete impl;
      }
    
    private:
      Dreiecksimplementierung* impl;
    };
    

    Benutzen wir hier einen SmartPointer (shared_ptr, unique_ptr) ist es schon wieder viel einfacher, da dann alles automatisch passiert.


Anmelden zum Antworten