next up previous contents index
Next: Initialisierung Wertzuweisung Up: Klassen Previous: Freunde

Konstruktoren

 

Beginn der Lebenszeit einer Variablen:

1.
Reserviere Speicherplatz für die Variable.
2.
Rufe einen Konstruktor auf, der die Variable initialisiert.

Ende der Lebenszeit einer Variablen:

1.
Rufe einen Destruktor auf, der notwendige Aufräumungsarbeiten ausführt.
2.
Gib den Speicher für die Variable wieder frei.

Primitive Datentypen

Für primitive Datentypen sind Konstruktoren und Destruktoren sehr einfach. Der Compiler kennt sie und wendet sie automatisch an.   Initialisierung kann auf drei verschiedenen Arten spezifiziert werden:

    initializer: 
       '=' assignment_expression | 
       '=' '{' initializer_list '}' |
       '(' expression_list ')' .

C++ Reference Manual

Die ``= expression''-Notation stammt aus C:

    int i = 7;
    complex z = complex(3.4,6);
    char *p = "hallo\n";

Die ``= initializer_list''-Notation ist ebenfalls aus C. Sie dient zur Initialisierung von Arrays und Structures:

    struct studi
    { char *name;
      long matrnr;
    } st_liste[] = {"Adam", 3567890,
                    "Eva",  3678901};

Die ``(expression_list)''-Notation stammt aus Simula. Wird meist für nicht-arithmetische Typen genommen:

     date today(25,4,1994);

Die Notationen 1 und 3 sind austauschbar (Geschmacksache):

    int i(7);
    date today = date(25,4,1994);
    complex z(3.4,6);

Bei fehlender Initialisierung werden  

Konstruktoren für Klassen

  Müssen vom Klassen-Designer zur Verfügung gestellt werden.

Konstruktoren haben den selben Namen wie die Klasse. Sie haben keinen Ergebnistyp und dürfen auch kein Ergebnis liefern.

    class date 
    {   int day, month, year;
     public:
        date(int, int, int); // Konstruktor-Dekl.
        void print();
    };
    // Konstruktor-Definition:
    date::date(int d, int m, int y) 
    { // Initialisierung durch Wertzuweisung:
      day = d; month = m; year = y; }

    ...
    date xmax(24,12,1997);       // Simula-Stil
    date today = date(17,4,1997); // C-Stil

Wie Elementfunktionen darf der Konstruktor auch innerhalb der Klassendeklaration definiert werden.

Eine andere Möglichkeit für die Initialisierung der Klassenelemente:  

    class date 
    {   int day, month, year;
     public:
        date(int, int, int); // Konstruktor-Dekl.
        void print();
    };
    // Konstruktor-Definition:
    date::date(int d, int m, int y) 
    : day(d), month(m), year(y) {}

Diese Initialisierungsliste initialisiert die Klassenelemente mit deren Konstruktor. Im Rumpf des Konstruktors ist in unserem Beispiel nichts mehr zu tun.

tex2html_wrap5169

   

Es darf beliebig viele Konstruktorfunktionen geben. Sie müssen in Anzahl und/oder Typ der Parameter unterscheidbar sein.

    class date 
    {   int day, month, year;
     public:
        date(int, int, int); // Konstruktor-Dekl.
        date(int);           // Konstruktor-Dekl.
        void print();
    };

    // Konstruktor-Definitionen:
    date::date(int d, int m, int y) 
    : day(d), month(m), year(y) {}

    date::date(int y)
    : year(y), day(1), month(1) {}

    ...
    date newyear(1999);

Der Default-Konstruktor

  Ein Default-Konstruktor ist ein Konstruktor ohne Parameter:

    class date 
    {   int day, month, year;
     public:
        date() { day=1; month=1; year=1956;}
    };

tex2html_wrap5171

Der Default-Konstruktor wird aufgerufen für  

Wenn eine Klasse überhaupt keinen Konstruktor hat, wird der Default-Konstruktor vom Compiler generiert:

    class date
    {   int day, month, year;
    };
    ...
   date irgendwann; // OK, aber unschoen!

Existiert jedoch ein Konstruktor, muß auch der Default-Konstruktor angegeben werden (wenn er benutzt wird):

   class date
   {   int day, month, year;
     public:
       date(int d, int m, int y)   
            : day(d),month(m) ,year(y) {};  
   };
   ...
   date irgendwann;    // FEHLER!

COMPILER:

    Too few arguments for constructor `date'
    Compilation failed

Der Copy-Konstruktor

 

Der Copy-Konstruktor hat folgende Aufgaben:  

Ein Copy-Konstruktor für Klasse X hat die Form

     X::X(const X&) // konstanter Referenzparameter

Wenn kein Copy-Konstruktor angegeben wird, wird er vom Compiler generiert. Der generierte Copy-Konstruktor erzeugt elementweise Kopien der Datenelemente des Objekts.  

Ein selbstgeschriebener Copy-Konstruktor  

    date(const date& original)
    {  day=original.day;
       month=original.month;
       year=original.year;
       cout << "Handmade Copy Constructor\n";
   } /* date */

Eigene Copy-Konstruktoren werden in der Regel nötig, wenn die Objekte dynamische Daten enthalten.

Beispiel:

    class student
    {   char *name;
        int matrnr;
      public:
        student(char *, int);   // Konstruktor
        void gross(void);
        void print();
    };
    void student::gross(void)
    { *name = *name - ' ';
    } 
    void student::print()
    {  cout << name << " " << matrnr << "\n";
    } 
    ...
    student erika("mustermann",3567890);
    student clone = erika;
    erika.gross();
    clone.print(); // Schreibt "Mustermann"

tex2html_wrap_inline5173 Elementweises Kopieren genügt nicht. Copy-Konstruktor selbst schreiben (z.B. mit strcpy).


next up previous contents index
Next: Initialisierung Wertzuweisung Up: Klassen Previous: Freunde

Peter Pfahler, 1997