Zum Inhalt springen

C++-Programmierung/ Im Zusammenhang mit Klassen/ Varianten

Aus Wikibooks


Definition

[Bearbeiten]

Eine Union ist eine Typdefinition zur Vereinigung verschiedener Typen auf einer Adresse. Dies erleichtert Redefinitionen oder die Verwendung von Variantentypen. Sie nimmt nicht mehrere Elemente nebeneinander auf, sondern zu jedem Zeitpunkt immer nur eines. Wird eine der Definitionsvarianten initialisiert, so werden die anderen damit implizit initialisiert, da sie auf der gleichen Adresse beginnen. Sie wird mit dem Schlüsselwort union deklariert:

union _Union1
{
  int a;
  float b;
  char[4] caC; // 32bit float/int angenommen
};

Erläuterung: Es wird ein Typ namens _Union1 definiert (von dem später Variablen angelegt werden können). Sein Inhalt kann aufgefasst werden entweder als ein int-Wert, oder als ein float-Wert, oder als ein char[4]-Array. Da alle drei Möglichkeiten jeweils 4 Bytes benötigen, werden später für eine Variable des Typs _Union1 vier Bytes reserviert.

Beispiel zur Verwendung:

_Union1 u1;   // Instanz erzeugen
u1.a = 10;  // jetzt ist in u1 ein int gespeichert
u1.b = 2.5; // jetzt ein float
            // damit hat u1.a möglicherweise keinen sinnvollen Wert mehr
ofstream DateiStream("xxx.data");
DateiStream << u1.caC; // Damit wird der Dateninhalt als Rohdaten verwendet

Im Beispiel wird eine Variable u1 angelegt: für sie werden 4 Byte Speicher reserviert. Diese 4 Bytes können als int-Wert aufgefasst/verwendet werden, oder als float-Wert verwendet werden, oder als char[4]. Das Beispiel "wandelt" dadurch das Bitmuster des float-Werts 2.5 in vier char-Zeichen und schreibt diese in die Datei xxx.data .

Eine Variable eines union-Typs benötigt so viel Speicher, wie die größte Inhalts-Variante. Die "kleineren Möglichkeiten" überdecken dann nur den "vorderen Teil" der größten Möglichkeit, ab der Startadresse.

Übliche Verwendungszwecke

[Bearbeiten]

Handhaben von Rohdaten

[Bearbeiten]

Bei Einsatz von Datenstrukturen mit fester Ausrichtung und kann mithilfe einer union die gesamte Datensammlung als Rohdaten aus dem Speicher betrachtet werden, beispielsweise mit einer anonymen union, die eine Datensammlungsstruktur beinhaltet und einen direkt ansprechbaren Zeiger auf deren Rohdaten enthält.

Binäre Typwandlung

[Bearbeiten]

Im obigen Beispiel wird das Bitmuster von 2.5f direkt als char[4] aufgefasst. Im Gegensatz dazu würde beispielsweise eine Wandlung

int i = (int) 4.8f ;

nicht das Bitmuster des float-Werts 4.8f in die Variable i übertragen, sondern den Zahlenwert 4.

Varianten

[Bearbeiten]

Beispiel: Eine Klasse "KFZ" soll die Fahrgestellnummer für beliebige PKW als Membervariable halten können. Innerhalb der EU ist dies eine 17-stellige Folge aus Großbuchstaben und Ziffern (z.B. char[17]). In einem Nicht-EU-Land könnte es aber eine Ganzzahl sein, die in eine (long) -Variable passt.

Mit einem

U_IDENT_NR union {
  char[17] eu;
  long     non_eu;
}

kann die Klasse KFZ beide Arten aufnehmen: Sie erhält eine Member-Variable

U_IDENT_NR  identifizierungsNummer;