Anzeigen: Object Pascal C++
Anzeigeeinstellungen

Initialisierung von Klassen

Aus Appmethod Topics
Wechseln zu: Navigation, Suche

Nach oben zu Konstruktoren - Index

Ein Objekt einer Klasse, das nur public-Elemente und keine Konstruktoren oder Basisklassen enthält (dies ist normalerweise eine Struktur), kann mit einer Initialisierer-Liste initialisiert werden. Hat eine Klasse einen Konstruktor, müssen ihre Objekte entweder initialisiert werden oder einen Standardkonstruktor haben. Der Standardkonstruktor wird für Objekte genutzt, die nicht explizit initialisiert werden.

Objekte von Klassen mit Konstruktoren können mit einer Liste von Ausdrücken in Klammern initialisiert werden. Diese Liste wird als Argumentliste für den Konstruktor verwendet. Eine Alternative dazu ist das Gleichheitszeichen (=), gefolgt von einem einzelnen Wert. Dieser Wert kann vom Typ des ersten Arguments sein, das ein Konstruktor dieser Klasse enthält. In diesem Fall gibt es keine weiteren Argumente, oder die restlichen Argumente haben Standardwerte. Als Initialisierungswert kann auch ein Objekt des Klassentyps verwendet werden. Im ersten Fall wird der zugehörige Konstruktor aufgerufen, um das Objekt zu erzeugen. Im zweiten Fall wird zur Initialisierung der Kopierkonstruktor aufgerufen.



 class X
 {
    int i;
 public:
    X();         // Funktionsrümpfe wurden der Übersichtlichkeit halber weggelassen.
    X(int x);
    X(const X&);
 };
 void main()
 {
    X one;        // Standardkonstruktor wird aufgerufen
    X two(1);     // Konstruktor X::X(int) wird verwendet
    X three = 1;  // ruft X::X(int) auf
    X four = one; // ruft X::X(const X&) zum Kopieren auf
    X five(two);  // ruft X::X(const X&) auf
 }



Der Konstruktor kann seinen Elementen auf zweierlei Arten Werte zuweisen:

1. Er kann die Werte als Parameter übernehmen und sie den Elementvariablen im Rumpf der Konstruktorfunktion zuweisen:



 class X
 {
    int a, b;
 public:
    X(int i, int j) { a = i; b = j }
 };



2. Er kann aber auch eine Initialisierer-Liste verwenden, die vor dem Funktionsrumpf steht:



 class X
 {
    int a, b, &c;  // Beachten Sie die Referenzvariable.
 public:
    X(int i, int j) : a(i), b(j), c(a) {}
 };



Eine Referenzvariable kann nur in einer Initialisierer-Liste initialisiert werden.

In beiden Fällen weist eine Initialisierung von X x(1, 2) x::a den Wert 1 und x::b den Wert 2 zu. Die zweite Methode - die Initialisierer-Liste - ist ein Mechanismus zur Übergabe von Werten an Basisklassen-Konstruktoren.

Anmerkung:  Basisklassen-Konstruktoren müssen als public oder protected deklariert sein, damit sie von einer abgeleiteten Klasse genutzt werden können.



 class base1
 {
    int x;
 public:
    base1(int i) { x = i; }
 };
 class base2
 {
    int x;
 public:
    base2(int i) : x(i) {}
 };
 class top : public base1, public base2
 {
    int a, b;
 public:
    top(int i, int j) : base1(i*5), base2(j+i), a(i) { b = j;}
 };



In dieser Klassenhierarchie würde eine Deklaration von top one(1, 2) die Initialisierung von base1 mit dem Wert 5 und von base2 mit dem Wert 3 ergeben. Die Initialisierungsmethoden lassen sich mischen.

Wie bereits oben erwähnt, werden die Basisklassen in der Reihenfolge ihrer Deklaration initialisiert. Anschließend erfolgt die Initialisierung der Elemente (ebenfalls in der Deklarationsreihenfolge), unabhängig von der Initialisierungsliste.



 class X
 {
   int a, b;
 public:
   X(int i, j) :  a(i), b(a+j) {}
 };



In dieser Klasse hat die Deklaration von X x(1,1) eine Zuweisung von 1 an x::a und von 2 an x::b zur Folge.

Basisklassen-Konstruktoren werden vor der Konstruktion der abgeleiteten Klassenelemente aufgerufen. Wenn sich die Werte der abgeleiteten Klasse ändern, hat dies keine Auswirkung auf die Erzeugung der Basisklasse.



 class base
 {
    int x;
 public:
    base(int i) : x(i) {}
 };
 class derived : base
 {
    int a;
 public:
    derived(int i) : a(i*10), base(a) { } // Vorsicht! Der An Base wird
                                          // uninitialisiertes ‘a’ übergeben
 };



Bei dieser Klassenkonstruktion führt der Aufruf eines derived d(1) nicht zum Wert 10 für das Basisklassen-Element x. Der an den Basisklassen-Konstruktor übergebene Wert ist undefiniert.

Wenn Sie eine Initialisierungsliste in einem Nichtinline-Konstruktor wünschen, platzieren Sie die Liste nicht in die Klassendefinition. Setzen Sie sie stattdessen an einen Punkt, an dem die Funktion definiert ist.



 derived::derived(int i) : a(i)
 {
   .
   .
   .
 }



Siehe auch

Meine Werkzeuge
In anderen Sprachen