Unions und ihre Risiken
Speicher zwischen Typen teilen
Unions und ihre Risiken ist eine kostenlose C++ Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C++ Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Was ist eine Union?
Eine union ermöglicht es mehreren Membern, denselben Speicherbereich gemeinsam zu nutzen. Zu jedem Zeitpunkt ist nur ein Member gültig, und die Union ist nur so groß wie ihr größtes Member.
#include <iostream>
union Number {
int i;
float f;
};
int main() {
Number n;
n.i = 42;
std::cout << n.i << "\n";
}Größe einer Union
Da sich die Member überlagern, entspricht sizeof einer Union der Größe ihres größten Members (zuzüglich möglicher Ausrichtungspolsterung) und nicht der Summe ihrer Größen.
#include <iostream>
union Mix { char c; int i; double d; };
int main() {
std::cout << sizeof(Mix) << "\n"; // size of double (often 8)
}Einen Member schreiben, einen anderen lesen
Das Schreiben in einen Member und das Lesen aus einem anderen ist das zentrale Risiko. Die Bits werden neu interpretiert, was meistens undefiniertes oder überraschendes Verhalten zur Folge hat.
#include <iostream>
union Bits { int i; float f; };
int main() {
Bits b;
b.f = 1.0f;
std::cout << b.i << "\n"; // reads float bits as int
}Nur ein aktiver Member
Der Member, in den Sie zuletzt geschrieben haben, ist der einzige, den Sie sicher lesen dürfen. Verfolgen Sie selbst, welcher Member „aktiv“ ist; die Union merkt sich das nicht.
#include <iostream>
union Value { int i; double d; };
int main() {
Value v;
v.d = 3.14; // d is active
std::cout << v.d << "\n";
}Das Tagged-Union-Muster
Um Unions sicher zu verwenden, kombinieren Sie sie mit einem Tag (einem Enum), das den aktiven Member speichert. Dies ist der manuelle Vorläufer von std::variant.
#include <iostream>
struct Tagged {
enum { Int, Double } tag;
union { int i; double d; };
};
int main() {
Tagged t; t.tag = Tagged::Int; t.i = 7;
if (t.tag == Tagged::Int) std::cout << t.i << "\n";
}Den richtigen Member lesen
Verzweigen Sie immer anhand des Tags, bevor Sie lesen. Das Lesen des falschen Members erzeugt unbrauchbare Werte.
#include <iostream>
struct Tagged {
enum { Int, Double } tag;
union { int i; double d; };
};
void print(const Tagged& t) {
if (t.tag == Tagged::Int) std::cout << "int " << t.i << "\n";
else std::cout << "double " << t.d << "\n";
}
int main() { Tagged t{Tagged::Double}; t.d = 2.5; print(t); }Nicht-triviale Member
Wenn Sie einen Member mit Konstruktor oder Destruktor (wie std::string) in einer Union verwenden, müssen Sie ihn manuell konstruieren und zerstören. Das ist fehleranfällig und ein weiterer Grund, std::variant zu bevorzugen.
Anonyme Unions
Eine anonyme Union hat keinen Namen; auf ihre Member wird direkt zugegriffen. Das ist innerhalb einer Struktur praktisch, aber die Regel für den aktiven Member gilt weiterhin.
#include <iostream>
struct Packet {
int kind;
union { int code; char letter; };
};
int main() {
Packet p; p.kind = 1; p.code = 99;
std::cout << p.code << "\n";
}Warum Unions riskant sind
Zusammenfassung der Gefahren:
- Die Union speichert nicht, welcher Member aktiv ist.
- Das Lesen eines inaktiven Members ist undefiniertes Verhalten.
- Nicht-triviale Typen erfordern eine manuelle Verwaltung ihrer Lebensdauer.
Wann Unions trotzdem nützlich sind
Unions bleiben für Aufgaben auf niedriger Ebene nützlich: zur Neuinterpretation von Bytes, zum Sparen von Speicher in speicherbeschränktem Embedded-Code oder zum Abbilden eines festen binären Layouts. Für Daten, die im Alltag „einer von mehreren Typen“ sind, sollten Sie die sicherere Alternative bevorzugen.
Auf dem Weg zu std::variant
std::variant ist eine typsichere Union, die den aktiven Typ für Sie verfolgt und eine Ausnahme auslöst, wenn Sie auf den falschen Typ zugreifen. Der restliche Kurs behandelt sie ausführlich.
Kurzer Test
Überprüfen Sie Ihr Verständnis von Unions.
Zusammenfassung
Sie haben Unions kennengelernt:
- Alle Member teilen sich einen Speicherblock.
- Nur der zuletzt beschriebene Member kann gültig gelesen werden.
- Verwenden Sie ein Tag (Enum), um den aktiven Member zu verfolgen.
- Bevorzugen Sie in modernem C++
std::variant, um mehr Sicherheit zu gewährleisten.
Häufig gestellte Fragen
Ist die Lektion „Unions und ihre Risiken“ kostenlos?
Ja — der vollständige Text von „Unions und ihre Risiken“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C++ Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Unions und ihre Risiken“?
Speicher zwischen Typen teilen Du übst C++ Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C++ Academy zu starten?
Keine Vorkenntnisse erforderlich. C++ Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Unions und ihre Risiken“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C++ Academy-Lektion Code schreiben und ausführen?
Ja. Jede C++ Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Scoped enum class
- Unions und ihre Risiken
- std::variant
- std::visit