Objekt und Klasse und Konstruktoren


  • Mod

    Objekt verhält sich zu Klasse wie Plätzchen zu Plätzchenform.

    Wozu will man mehrere Konstruktoren für ein Objekt besitzen

    Warum nicht? willst du deine Plätzchen nur mit einem Teig backen können?

    und wieso dann nur einen Destruktor?

    Ok, hier bricht die Plätzchenanalogie etwas zusammen 🙂
    Der Destruktor eines Objekts zerstört dieses unabhängig von allen anderen Dingen. Was sollte man so einem Destruktor auch sagen? Das einzige, was er wissen muss, ist, welches Objekt er zerstören soll. Und das heißt, dass es genau eine Destruktorvariante gibt, nämlich die, die als (verstecktes) Argument das zu zerstörende Objekt erhält und sonst nichts.



  • SeppJ schrieb:

    Ok, hier bricht die Plätzchenanalogie etwas zusammen 🙂

    Quatsch. Du kannst mit deinem eigenen (einzigen) Mund alle Plätzchen essen (zerstören), ganz egal aus welchem Teig sie gebacken sind 😃


  • Mod

    Aber viele verschiedene Münder können Plätzchen essen 😞



  • Eine Klasse ist eine Beschreibung für eine Instanz (Objekt). Nach dieser Beschreibung wird dann eine Instanz gebaut. So ein Beschreibung besteht aus Datenelementen (du beschreibst, was den Zustand einer Instanz repräsentieren soll) und Elementfunktionen (du beschreibst, was eine Instanz können soll).

    Eine Instanz ist etwas Lebendiges, sagen wir ein Akteur, mit dem du Dinge machen kannst. Welche Dinge dein Akteur machen kann, sagen die Elementfunktionen. Das Ergebnis einer Aktion sagen dann die Datenelemente. Die Datenelemente repräsentieren den aktuellen Zustand deiner Instanz.

    Beispiel: Du hast eine Klasse Auto. Du erstellst ein Auto names KITT. Dann sagst du KITT.anhalten(). Das Ergebnis ist dann z.B. Datenelement kmh=0.

    Ja ein Konstruktor initialisiert (baut) eine Instanz. Du kannst beliebig viele unterschiedliche Konstruktoren haben. Du kannst mehrere Konstruktoren haben, weil du willst, dann Instanzen auf unterschiedliche Art gebaut werden. Du willst ein Auto mit 50 PS bauen und du willst ein Auto mit 260 PS bauen. Wieso sollte es mehrere Destruktoren geben?

    Hoffe, die Veranschaulichungen helfen dir weiter.



  • Die Antworten haben mir sehr geholfen. Danke sehr



  • Das es nur einen Destructor gibt, ist allein dem "maximale Effizienz" Ansatz von C++ geschuldet. Es waere kein Problem dem Konstruktor der Klasse einfach schon z.b. einen Funktionspointer mitzugeben, mit welchem man unter mehreren Destruktoren wechseln kann. Allein dieser muss pro Instanz gespeichert werden, und daher passiert dies eben nicht. Troztdem hat C++ schon eine Mechanik eingebaut, man kann den Destruktor virtual machen und dann in einer abgeleiteten Klasse überschreiben. Beim Konstruieren kann man sich dann den Destruktor waehlen. Das Objekt legt in der vtable die Daten ab um spaeter den passenden Destruktor zu finden, gab es vorher keine virtuelle Methode bezahlt man hier also diesen Preis.



  • TGGC schrieb:

    Das es nur einen Destructor gibt, ist allein dem "maximale Effizienz" Ansatz von C++ geschuldet.

    Ich würde nicht sagen "allein".
    Selbst wenn man die runtime Kosten (Zeit + Speicher) ignoriert stellt sich immer noch die Frage "wozu?".
    Und da fällt mir einfach kein guter Grund ein.
    Also ich wüsste kein Beispiel wo ich, je nachdem wie das Objekt konstruiert wurde, einen anderen Destruktor verwenden wollen würde.



  • TGGC schrieb:

    Das es nur einen Destructor gibt, ist allein dem "maximale Effizienz" Ansatz von C++ geschuldet.

    Unfug.



  • hustbaer schrieb:

    TGGC schrieb:

    Das es nur einen Destructor gibt, ist allein dem "maximale Effizienz" Ansatz von C++ geschuldet.

    Ich würde nicht sagen "allein".
    Selbst wenn man die runtime Kosten (Zeit + Speicher) ignoriert stellt sich immer noch die Frage "wozu?".
    Und da fällt mir einfach kein guter Grund ein.
    Also ich wüsste kein Beispiel wo ich, je nachdem wie das Objekt konstruiert wurde, einen anderen Destruktor verwenden wollen würde.

    Du hast noch nie in einem Destructor ein if oder switch Statement verwendet? Immer wenn in einem Destructor Code ausgefuehrt wird, der dynamisch vom Zustand des Programms abhaengt, waeren mehrere Destruktoren doch lediglich syntaktischer Zucker um das Gleiche zu erreichen. Spontan fallen mir da unions ein.

    Mit der Frage "wozu" kann man doch jede Funktion aus einer Programmiersprache entfernen, welche ueber eine Turingmaschine hinausgeht...



  • TGGC schrieb:

    Du hast noch nie in einem Destructor ein if oder switch Statement verwendet?

    Doch, klar. Aber kaum mit Bedingungen die nur immutable State prüfen.

    TGGC schrieb:

    Immer wenn in einem Destructor Code ausgefuehrt wird, der dynamisch vom Zustand des Programms abhaengt, waeren mehrere Destruktoren doch lediglich syntaktischer Zucker um das Gleiche zu erreichen.

    Nur wenn der gesamte Destruktor als

    T::~T()
    {
        if (condition)
        {
            // ...
        }
        else
        {
            // ...
        }
    }
    

    geschrieben werden kann.
    Die Fälle wo das sinnvoll ist beschränken sich also auf Code wo die oben gezeigte Form ohne Codeduplizierung möglich wäre.

    Weiters eben die Sache mit dem mutable State. Bei so ziemlich allen Beispielen die mir einfallen müsste es die Möglichkeit geben den "designated destructor" nachträglich zu ändern. Das würde die Spezifikation verkomplizieren. Man müsste definieren wie man den dtor nachträglich ändern kann. Man müsste definieren was der compilerdefinierte operator = macht. Usw.

    Und am Ende wäre der Nutzen immer noch so klein, dass es sich mMn. einfach nicht auszahlt den Sprachstandard und den Lernaufwand dadurch deutlich zu vergrössern.
    Wenn man halbwegs durchgängig und feingranular RAII einsetzt ist die Anzahl der Klassen wo man überhaupt explizit definierte Destruktoren hat schonmal klein. Und nur in einem Bruchteil davon werden control-flow Statements vorkommen die man durch das "mehrere Destruktoren" Feature ersetzen könnte.

    TGGC schrieb:

    Mit der Frage "wozu" kann man doch jede Funktion aus einer Programmiersprache entfernen, welche ueber eine Turingmaschine hinausgeht...

    Nicht wenn man damit meint dass man den Aufwand dem Nutzen gegenüberstellen sollte.
    (Wobei zum Aufwand natürlich nicht nur der Aufwand zählt der nötig ist um das Feature zu spezifizieren und in den Compilern zu implementieren, sondern auch wie oben schon erwähnt der Lernaufwand für neue Programmierer.)
    Ich dachte eigentlich dass klar war dass ich es so gemeint habe.



  • Mit den gleichen Argumenten könntest du z.b. auch mehrere Konstruktoren ablehnen. Der Unterschied ist lediglich, das es dieses Feature schon gibt und du deshalb gewöhnt bist Anwendungen dafür zu kennen.



  • Nein, könnte ich nicht.
    Liest du überhaupt was ich schreibe?
    Oder willst du mich einfach nur aufziehen?
    Alter Schwede...





  • hustbaer schrieb:

    Nein, könnte ich nicht.

    Wer sollte dich hindern?


  • Mod

    TGGC schrieb:

    hustbaer schrieb:

    Nein, könnte ich nicht.

    Wer sollte dich hindern?

    Logik? Das Argument bricht doch schon beim allerersten Schritt zusammen, wenn es um Parameter für die Konstruktion geht.



  • Kosten:

    Mehrere Konstruktoren zu erlauben macht in einer Sprache die bereits Overloads erlaubt nichts wesentlich komplizierter. Die Overload-Resolution Regeln gibt es bereits, der Ctor wird ganz normal anhand dieser ausgewählt.
    Davon abgesehen wird nichts verkompliziert. Es müssen keine speziellen Regeln definiert werden was beim operator = zu passieren hat, es muss kein zusätzlicher State in das Objekt rein.

    Nutzen:

    Mehrere Konstruktoren sind nötig um flexible konsturierbarkeit von Klassen zu ermöglichen wenn diese...
    * const Member haben
    * Member haben die nur per Ctor initialisiert werden können (d.h. nicht default konstruiert und danach so verändert werden können dass sie "passen").
    Weiters erspart man sich dadurch lauter "named Constructor" Funktionen zu basteln.

    Weiters sind mehrere Konstruktoren nötig für kopierbare und konvertierbare Klassen.

    ---

    Der Nutzen ist also ziemlich klar und mMn. auch ziemlich gross, und die Kosten sind minimal.
    Also genau umgekehrt wie beim Destruktor.



  • Erhard Henkes schrieb:

    schau mal hier: http://www.cpp-tutor.de/cpp/le10/ctor_dtor.html

    An wen ist das gerichtet und was soll er/sie da "schauen"? Einen ca. 10 seitigen Artikel mit nur "schau mal da" zu verlinken, in dem auf den ersten Blick nichts zu sehen ist was wirklich zum Thema passt, finde ich ein bisschen unpassend.



  • "The data items and the functions that manipulate them are combined into a structure called a class."

    Ist jetzt ein Objekt und eine Klasse das gleiche oder was ist da der genaue Unterschied?

    Dann noch eine Frage aus einem anderen Kapitel. Dort heisst es:

    "More than one constructor, but only one destructor, can be declared for a class"

    Also ein Konstruktor erzeugt und initialisiert ein Objekt und derer kann es mehrerer pro Objekt geben, aber ein Objekt kann nur einen einzige Destruktor besitzen. Was hat es denn damit auf sich? Wozu will man mehrere Konstruktoren für ein Objekt besitzen und wieso dann nur einen Destruktor?

    Ich finde, dass dieses Tutorial und speziell dieses Kapitel gut zu obiger allgemeiner Fragestellung passt.



  • OK, danke, damit kann ich mehr anfangen 🙂

    Also war es an den OP gerichtet...



  • SeppJ schrieb:

    Logik? Das Argument bricht doch schon beim allerersten Schritt zusammen, wenn es um Parameter für die Konstruktion geht.

    Bei welchem allerersten Schritt soll denn welches Argument aus welchem Grund genau zusammenbrechen?

    hustbaer schrieb:

    Kosten:

    Mehrere Konstruktoren zu erlauben macht in einer Sprache die bereits Overloads erlaubt nichts wesentlich komplizierter. Die Overload-Resolution Regeln gibt es bereits, der Ctor wird ganz normal anhand dieser ausgewählt.
    Davon abgesehen wird nichts verkompliziert. Es müssen keine speziellen Regeln definiert werden was beim operator = zu passieren hat, es muss kein zusätzlicher State in das Objekt rein.

    Nutzen:

    Mehrere Konstruktoren sind nötig um flexible konsturierbarkeit von Klassen zu ermöglichen wenn diese...
    * const Member haben
    * Member haben die nur per Ctor initialisiert werden können (d.h. nicht default konstruiert und danach so verändert werden können dass sie "passen").
    Weiters erspart man sich dadurch lauter "named Constructor" Funktionen zu basteln.

    Weiters sind mehrere Konstruktoren nötig für kopierbare und konvertierbare Klassen.

    ---

    Der Nutzen ist also ziemlich klar und mMn. auch ziemlich gross, und die Kosten sind minimal.
    Also genau umgekehrt wie beim Destruktor.

    Selbst wenn man mal davon ausgehen wuerde, das obige Aussagen korrekt waeren:
    a) Du hast die Kosten und Nutzen der Destruktor gar nicht analysiert, wie kannst du also "genau umgekehrt" daraus folgern?
    b) Willst du jetzt sagen das ein Feature nur dann in C++ eingebaut werden sollte, wenn sein Nutzen mindestens so hoch wie der von Konstruktoren und die Kosten nicht hoeher als der von Konstruktoren ist?
    c) Wie genau sollen Kosten und Nutzen ueberhaupt als konkreter Wert berechnet werden um so eine quantitive Einschaetzung abzugeben?


Anmelden zum Antworten