Konstruktor und Destruktor

Eine Klasse kann beliebig viele Konstruktoren haben. Der Sinn eines Konstruktors ist, ein Objekt zu erzeugen. Er muss Ressourcen besorgen und das Objekt in einen gültigen Zustand versetzen. Der Destruktor zerstört das Objekt. Er wird automatisch aufgerufen, wenn das Objekt stirbt. Man darf ihn deshalb nicht selber aufrufen (Ausnahme: placement new).

Ein Konstruktor mit nur einem Parameter kann als Umwandlungsoperator verwendet werden:

    class Integer
    {
    public:
      Integer(int dummy)
      {
      }
    };

    void foo(Integer dummy)
    {
    }

    int main()
    {
      foo(5);
    }

Der Aufruf von foo(5) ist legal, da 5 ja ein int ist und ein int sich mit Hilfe des Konstruktors von Integer in einen Integer verwandeln kann. Diese Umwandlung ist allerdings nicht immer erwünscht, da es zu Situationen kommen kann, in denen die Umwandlung ungewollt stattfindet. Deshalb kann man diese verbieten:

    class Integer
    {
    public:
      explicit Integer(int dummy)
      {
      }
    };

    void foo(Integer dummy)
    {
    }

    int main()
    {
      //foo(5); //geht nicht
      foo(Integer(5)); //geht
    }

Hier ist der Aufruf von foo(5); falsch, da 5 nicht mehr in Integer umgewandelt werden kann. Wir müssen diese Umwandlung händisch machen, indem wir Integer(5) schreiben. Dies erzeugt ein temporäres Integer Objekt. Die automatische Variante macht es genauso, nur dass wir den Aufruf von Integer(5) nicht sehen, da er 'implizit' von statten geht. Hier sehen wir schon die Gefährlichkeit von temporären Objekten - denn sie verstecken sich sehr gut.

Es gibt 2 besondere Konstruktoren: den Standard (oder Default) Konstruktor und den Kopier-Konstruktor (Copy Constructor). Diese beiden Konstruktoren werden automatisch vom Compiler erstellt. Der Default Konstruktor ruft für jede Member Variable den Default Konstruktor auf, während der Kopierkonstruktor für alle Member Variablen den Kopierkonstruktor aufruft.

Jeder Konstruktor, der ohne Parameter aufgerufen werden kann, ist ein Default Konstruktor. Ein Konstruktor ist also auch dann ein Default Konstruktor wenn jeder Parameter einen default Wert hat. Wenn wir selber einen Konstruktor erstellen, erstellt der Compiler keinen Standard Konstruktor mehr. Standard Konstruktoren sollten generell vermieden werden, da ein Objekt in den meisten Fällen bestimmte Daten braucht um richtig zu funktionieren. Default Werte reichen da nicht immer aus.

Ein Kopierkonstruktor wird dazu verwendet eine Kopie anzulegen: Foo f(x); f ist eine Kopie von x. Zwischen Foo f(x); und Foo f=x; gibt es einen kleinen aber feinen Unterschied (direct initialization und copy initialization).

top