C++
Gewerkschaften
Suche…
Bemerkungen
Gewerkschaften sind sehr nützliche Werkzeuge, haben jedoch einige wichtige Einschränkungen:
Gemäß dem C ++ - Standard ist es undefiniertes Verhalten, auf ein Element einer Union zuzugreifen, das nicht das zuletzt geänderte Mitglied war. Obwohl viele C ++ - Compiler diesen Zugriff auf genau definierte Weise zulassen, handelt es sich dabei um Erweiterungen, die nicht für alle Compiler gewährleistet werden können.
Eine
std::variant
(seit C ++ 17) ist wie eine Union. Sie sagt nur, was sie aktuell enthält (Teil des sichtbaren Status ist der Typ des Werts, den er zu einem bestimmten Zeitpunkt enthält: erzwingt nur den Zugriff auf Werte, der nur geschieht zu diesem Typ).Bei Implementierungen werden Mitglieder unterschiedlicher Größe nicht unbedingt an derselben Adresse ausgerichtet.
Grundlegende Funktionen der Union
Gewerkschaften sind eine spezialisierte Struktur, in der sich alle Mitglieder überlappendes Gedächtnis belegen.
union U {
int a;
short b;
float c;
};
U u;
//Address of a and b will be equal
(void*)&u.a == (void*)&u.b;
(void*)&u.a == (void*)&u.c;
//Assigning to any union member changes the shared memory of all members
u.c = 4.f;
u.a = 5;
u.c != 4.f;
Typische Verwendung
Unions sind hilfreich, um die Speichernutzung für exklusive Daten zu minimieren, z.
struct AnyType {
enum {
IS_INT,
IS_FLOAT
} type;
union Data {
int as_int;
float as_float;
} value;
AnyType(int i) : type(IS_INT) { value.as_int = i; }
AnyType(float f) : type(IS_FLOAT) { value.as_float = f; }
int get_int() const {
if(type == IS_INT)
return value.as_int;
else
return (int)value.as_float;
}
float get_float() const {
if(type == IS_FLOAT)
return value.as_float;
else
return (float)value.as_int;
}
};
Undefiniertes Verhalten
union U {
int a;
short b;
float c;
};
U u;
u.a = 10;
if (u.b == 10) {
// this is undefined behavior since 'a' was the last member to be
// written to. A lot of compilers will allow this and might issue a
// warning, but the result will be "as expected"; this is a compiler
// extension and cannot be guaranteed across compilers (i.e. this is
// not compliant/portable code).
}