Wann würde jemand eine Gewerkschaft benutzen? Ist es ein Überbleibsel aus den C-only Tagen?
Habe ich gelernt, aber nicht wirklich an die Gewerkschaften. Jedes C-oder C++ - text, den ich gehen durch Sie stellt, (manchmal im Vorbeigehen), aber Sie neigen dazu, sehr wenige praktische Beispiele, warum oder wo Sie zu nutzen. Wann würden die Gewerkschaften hilfreich sein, in ein modernes (oder auch alte) Fall? Meine nur zwei erraten wäre, Programmierung von Mikroprozessoren, wenn Sie haben sehr begrenzten Speicherplatz, mit zu arbeiten, oder wenn Sie die Entwicklung einer API (oder so ähnlich) und Sie erzwingen möchten, dass die Endbenutzer haben nur eine Instanz von mehreren Objekten/Typen gleichzeitig. Sind diese beiden Vermutungen auch nur annähernd richtig?
InformationsquelleAutor der Frage Russel | 2011-01-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gewerkschaften sind in der Regel verwendet, mit dem Unternehmen eine Diskriminator: eine variable, die angibt, welche Felder in der union gültig ist. Zum Beispiel, sagen wir, Sie möchten, erstellen Sie Ihre eigenen Variante Typ:
Dann würden Sie es verwenden, wie:
Dies ist eigentlich ein ziemlich verbreitetes idiom, speziell auf Visual Basic-Interna.
Für ein echtes Beispiel sehen, SDL SDL_Event union. (eigentliche source-code hier). Es ist ein
type
Feld an der Spitze der union, und das gleiche Feld wiederholt sich auf jeder SDL_*Event-Struktur. Dann Griff das richtige Ereignis müssen Sie prüfen, den Wert dertype
Feld.Die Vorteile sind einfach: es ist ein single-Datentyp, um alle Ereignis-Typen, ohne unnötigen Speicher.
InformationsquelleAutor der Antwort vz0
Ich finde C++ Gewerkschaften ziemlich cool. Es scheint, dass die Menschen in der Regel denke nur an die use-case, wo man will, ändern Sie den Wert eines union-Instanz "in-place" (die, wie es scheint, nur dazu dient, den Speicher zu speichern oder auszuführen zweifelhaft Konvertierungen).
In der Tat, der Gewerkschaften, von großer Kraft, wie eine software-engineering-tool auch wenn Sie nie ändern Sie den Wert einer union-Instanz.
Anwendungsfall 1: das Chamäleon
Mit den Gewerkschaften, Sie neu zu gruppieren einer Anzahl von beliebigen Klassen unter einer Bezeichnung, die nicht ohne ähnlichkeiten mit dem Fall von einer Basis-Klasse und Ihrer abgeleiteten Klassen. Was ändert sich, jedoch ist das, was Sie tun und nicht tun können, die mit einer bestimmten union-Instanz:
Scheint es, dass der Programmierer sich sicher sein, den Typ des Inhalts einer angegebenen union Instanz, wenn er es benutzen möchte. Es ist der Fall in der Funktion
f
oben. Allerdings, wenn eine Funktion erhalten einen union-Instanz als argument übergeben, wie es der Fall mitg
oben, dann würde es nicht wissen, was zu tun. Das gleiche gilt für Funktionen, die Rückkehr einer union-Instanz finden Sie unterh
: wie will der Anrufer wissen, was drin ist?Wenn ein union-Instanz wird nie als argument übergeben oder als Rückgabewert, dann ist es bestimmt noch ein sehr eintöniges Leben, mit Spitzen von Aufregung, wenn der Programmierer entscheidet, seinen Inhalt zu ändern:
Und das ist die (un -) beliebte Falle der Gewerkschaften. Ein anderer Anwendungsfall ist, wenn ein union-Instanz kommt mit etwas, das erzählt Sie Ihren Typ.
Use case 2: "Schön, Sie zu treffen, ich bin
object
vonClass
"Angenommen, ein Programmierer gewählt, um immer paar bis ein union-Instanz mit Typ-Deskriptor (ich überlasse es dem Leser frei, sich vorstellen, eine Implementierung für ein solches Objekt). Diese Niederlagen der Zweck der union selbst wenn das, was der Programmierer will, um Speicherplatz zu sparen und die Größe des type-descriptor ist nicht unerheblich in Bezug auf diese von der union. Aber nehmen wir an, dass es von entscheidender Bedeutung, dass die union Instanz sein könnte als argument übergeben oder als Rückgabewert mit der angerufene oder Anrufer-nicht zu wissen, was drin ist.
Dann hat der Programmierer zu schreiben
switch
control-flow-statement zu sagen, Bruce Wayne abgesehen von einem Holzstab oder etwas vergleichbares. Es ist nicht allzu schlimm, wenn es gibt nur zwei Arten von Inhalten in der union, aber offensichtlich ist die union nicht skaliert nicht mehr.Use case 3:
Als die Autoren der eine Empfehlung für die ISO-C++ - Standard steckte es zurück in 2008,
Und jetzt ein Beispiel mit einem UML-Klassendiagramm:
Die situation im Klartext: ein Objekt der Klasse kann Objekte von jeder Klasse unter B1, ..., Bn, und höchstens einer von jedem Typ, mit n ist ein ziemlich große Zahl, sagen mindestens 10.
Wir nicht wollen, um zusätzliche Felder hinzuzufügen (Daten-Mitglieder) zu Einer etwa so:
weil n variieren können, (wir könnten hinzufügen möchten Bx-Klassen zu mischen), und da würde ein Chaos mit Konstruktoren und weil die Objekte in Anspruch nehmen würde, sehr viel Platz.
Könnten wir eine verrückte Behälter
void*
Zeiger aufBx
Objekte mit Gips, um Sie abzurufen, aber das ist fugly und so C-style... aber noch wichtiger ist, die würde lassen Sie uns mit dem Leben von vielen dynamisch zugewiesenen Objekte zu verwalten.Statt, was getan werden kann, ist dies:
Dann, um den Inhalt einer union-Instanz aus
data
verwenden Siea.get(TYPE_B2).b2
" und ähnliches, woa
ist eine KlasseA
Instanz.Dies ist umso mächtiger, da die Gewerkschaften sind uneingeschränkt in C++11. Sehen das Dokument verknüpft oben oder dieser Artikel für details.
InformationsquelleAutor der Antwort jrsala
Ein Beispiel ist der embedded-Bereich, wo jedes bit eines Registers kann etwas anderes bedeuten. Zum Beispiel, eine union von einem 8-bit-Ganzzahl und eine Struktur mit 8 separaten 1-bit-bitfields können Sie entweder ein bit oder das ganze byte.
InformationsquelleAutor der Antwort Kevin
Herb Sutter schrieb in GOTW vor etwa sechs Jahren, mit Schwerpunkt Hinzugefügt:
Und für ein weniger nützliches Beispiel, siehe die lange, aber ergebnislose Frage gcc, strict-aliasing und Gießen durch eine Gewerkschaft.
InformationsquelleAutor der Antwort Joseph Quinsey
Nun, ein Beispiel use-case ich denken kann, ist dies:
Können Sie dann den Zugriff auf die 8-bit-separate Teile, die 32-bit-block der Daten; aber bereiten Sie sich auf potenziell gebissen werden von endian.
Dies ist nur ein hypothetisches Beispiel, aber wenn Sie möchten, aufteilen der Daten in einem Feld in Einzelteile mögen Sie dieses, Sie könnten einen union.
Dass heißt, es gibt auch eine Methode, die endian-sicher:
Zum Beispiel, seit, Binär operation konvertiert werden, indem der compiler die richtige endianness.
InformationsquelleAutor der Antwort
Gewerkschaften sind nützlich beim Umgang mit byte-Ebene (low level) Daten.
Einer meiner letzten Verwendung war auf IP-Adresse Modellierung, die sieht wie folgt aus :
InformationsquelleAutor der Antwort YeenFei
Einige Verwendungsmöglichkeiten für die Gewerkschaften:
Sparen Speicherplatz, wenn Felder sind abhängig von bestimmten Werten:
Grep include-Dateien für die Verwendung mit Ihrem compiler. Sie finden Dutzende bis Hunderte verwendet von
union
:InformationsquelleAutor der Antwort wallyk
Beispiel, wenn ich habe eine union:
dies ermöglicht mir den Zugriff auf meine Daten als array oder die Elemente.
Ich habe eine union zu haben, die unterschiedlichen Begriffe auf den gleichen Wert. In der Bildverarbeitung, egal ob ich arbeiten war auf Spalten oder die Breite oder die Größe in X-Richtung, kann es verwirrend werden. Zu alleve dieses problem, ich benutze einen union, so weiß ich, welche Beschreibungen gehen zusammen.
InformationsquelleAutor der Antwort DannyK
Gewerkschaften bieten Polymorphismus in C.
InformationsquelleAutor der Antwort Null Set
Eine brillante Verwendung der union-memory-alignment, das fand ich in der PCL(Point Cloud Library) - source-code. Die einzigen Daten die Struktur in der API kannst zwei Architekturen: CPU mit SSE-Unterstützung sowie die CPU ohne SSE-support. ZB: die Datenstruktur für PointXYZ ist
Den 3 Schwimmern sind gepolstert und mit einem zusätzlichen Schwimmer für die SSE-Ausrichtung.
Also für
Kann der Benutzer den access point.Daten[0] oder Punkt.x (abhängig von der SSE-Unterstützung) für den Zugriff auf sagen, die x-Koordinate.
Mehr ähnliche bessere Nutzung details sind auf folgendem link: PCL-Dokumentation PointT Typen
InformationsquelleAutor der Antwort Shubham Verma
Den
union
Schlüsselwort, während noch in C++031ist vor allem ein überbleibsel aus der C-Tage. Das eklatanteste Problem ist, dass es funktioniert nur mit POD1.Die Idee der union, ist jedoch noch vorhanden, und in der Tat die Boost-Bibliotheken verfügen über eine union-wie Klasse:
Welche hat die meisten Vorteile, die von der
union
(wenn nicht alle), und fügt hinzu:In der Praxis hat sich gezeigt, dass es äquivalent zu einer Kombination von
union
+enum
und zudem, dass es so schnell (währendboost::any
ist mehr der Bereich derdynamic_cast
seit es nutzt RTTI).1Gewerkschaften wurden aktualisiert in C++11 (uneingeschränkte Gewerkschaften), und kann jetzt mit Objekten mit Destruktoren, obwohl der Benutzer ruft den Destruktor manuell (auf die derzeit aktive union-Mitglied). Es ist noch viel einfacher zu bedienen Varianten.
InformationsquelleAutor der Antwort Matthieu M.
Aus der Wikipedia-Artikel über die Gewerkschaften:
InformationsquelleAutor der Antwort thkala
Können sagen, Sie haben n verschiedene Arten von Konfigurationen (nur als ein set von Variablen, die Definition von Parametern). Durch die Verwendung einer enumeration des Konfigurations-Typen können Sie definieren eine Struktur, die die ID der Konfiguration geben, zusammen mit einer union, all die verschiedenen Arten von Konfigurationen.
Diese Weise, wo immer Sie passieren die Konfiguration verwenden können, die ID zu bestimmen, wie zu interpretieren die Daten aus der Konfiguration, aber die Konfigurationen waren riesig, Sie wäre nicht gezwungen, parallele Strukturen, für jede mögliche Art Platz verschwenden.
InformationsquelleAutor der Antwort Gavin H
Einen letzten Schub auf die bereits hohe Bedeutung des unions wurde von den Strict-Aliasing-Regel eingeführt in der letzten version der C-standard.
Die Sie verwenden können Gewerkschaften tun, um Typ-Zweideutigkeiten ohne Verletzung der C-standard.
Dieses Programm hat unspezifisch Verhalten (weil ich davon ausgehe, dass
float
undunsigned int
haben die gleiche Länge), aber nicht Undefiniertes Verhalten (siehe hier).InformationsquelleAutor der Antwort
Hinzufügen möchte ich, dass ein gutes praktisches Beispiel für die Verwendung von union - Umsetzung der Formel-Rechner/Dolmetscher oder einige Art von Sie es in der Berechnung(zum Beispiel, die Sie verwenden möchten modificable während der Laufzeit teilen Sie Ihre computing-Formeln - lösen von Gleichung numerisch - nur ein Beispiel).
So können Sie definieren möchten, zahlen/Konstanten, die von unterschiedlichen Typen(integer, floating-point, auch mit komplexen zahlen) wie folgt aus:
So sparen Sie Speicher-und, was noch wichtiger ist - vermeiden Sie eine dynamische Zuweisungen für wahrscheinlich extreme Menge(wenn Sie verwenden eine Menge von run-time definiert-Nummern) von kleinen Objekten(im Vergleich zu Implementierungen durch Klassen-Vererbung/Polymorphismus). Aber was noch interessanter ist, man kann immer noch nutzen Sie die Kraft des C++ Polymorphismus(wenn Sie fan des double-dispatching, zum Beispiel 😉 mit dieser Art von Struktur ist. Fügen Sie einfach eine "dummy" - Schnittstelle Zeiger auf parent-Klasse für alle Zahl-Typen als ein Feld dieser Struktur, die auf diese Instanz anstelle von/zusätzlich zu den raw-Typ, oder verwenden Sie eine gute, alte C-Funktionszeiger.
so dass Sie verwenden können, Polymorphismus statt des Typs prüft, mit Schalter(Art) - mit Speicher-effiziente Implementierung(keine dynamische Allokation kleiner Objekte) - wenn Sie es brauchen, natürlich.
InformationsquelleAutor der Antwort Mastermind
Vom http://cplus.about.com/od/learningc/ss/lowlevel_9.htm:
InformationsquelleAutor der Antwort ανώνυμος
Gewerkschaften bieten eine Möglichkeit, zu manipulieren, um unterschiedliche Arten von Daten in einem einzigen Bereich der Lagerung ohne die Einbettung jeder Maschine unabhängige Informationen in das Programm
Sie sind Analog zu Variante records in pascal
Als ein Beispiel, wie könnte gefunden werden, in einer compiler-Symboltabelle-manager an, dass ein
Konstante kann einen int, einen float oder einen character-Zeiger. Der Wert einer bestimmten Konstanten
muss in einer variable gespeichert werden von der richtigen Art, aber es ist am meisten bequem für die Tisch-Verwaltung, wenn der Wert nimmt die gleiche Menge an Speicher und ist an der gleichen Stelle gespeichert, unabhängig von dessen Typ. Dies ist der Zweck der union - eine einzige variable, kann berechtigterweise halten Sie einen beliebigen der verschiedenen Typen. Die syntax basiert auf Strukturen:
Die variable u wird groß genug für die größte der drei Arten; die genaue Größe ist von der Implementierung abhängig. Jeder dieser Typen zugeordnet werden können u und dann in
Ausdrücke, so lange, wie die Verwendung konsistent ist
InformationsquelleAutor der Antwort Khushal
In der Anfangszeit von C (z.B. als dokumentierte in 1974), alle Strukturen, die einen gemeinsamen Namensraum für Ihre Mitglieder. Jedes Mitglied name wurde im Zusammenhang mit einem Typ und einem offset; wenn "wd_woozle" wurde ein "int" bei offset 12, dann einen Zeiger
p
jeder Struktur-Typ,p->wd_woozle
wäre äquivalent zu*(int*)(((char*)p)+12)
. Die Sprache erforderlich, dass alle Mitglieder von allen Strukturen, die Typen haben eindeutige Namen außerdass es ausdrücklich erlaubt die Wiederverwendung von Elementnamen in Fällen, in denen jede Struktur, wo Sie verwendet wurden, behandelten Sie wie einen gemeinsamen anfangs-Sequenz.Die Tatsache, dass Struktur-Typen verwendet werden könnten promiscuously es möglich gemacht haben, die Strukturen so Verhalten, als wäre Sie enthielten überlappende Felder. Beispiel-Definitionen:
code deklarieren Sie eine Struktur vom Typ "float1", und verwenden Sie dann "Mitglieder" b0...b3, um den Zugriff auf die einzelnen bytes darin. Wenn die Sprache geändert wurde, so dass jede Struktur erhalten würde, einen separaten Namensraum für seine Mitglieder, code, stützte sich auf die Fähigkeit, Zugriff auf Dinge mehrere Möglichkeiten brechen würde. Die Werte der Trennung von namespaces für verschiedene Struktur-Typen ausreichend war, zu verlangen, dass dieser code geändert werden, um es aufnehmen, aber die Wert solcher Techniken war ausreichend für die Begründung der Erweiterung der Sprache weiter zu fördern.
Code, die geschrieben worden war, zu nutzen, die Fähigkeit zum Zugriff auf den Speicher innerhalb einer
struct float1
als wäre es einstruct byte4
gemacht werden konnten, in der neuen Sprache durch das hinzufügen einer Erklärung:union f1b4 { struct float1 ff; struct byte4 bb; };
Deklaration von Objekten als Typunion f1b4;
eher alsstruct float1
und ersetzen Zugriffe auff0
b0
b1
usw. mitff.f0
bb.b0
bb.b1
usw. Zwar gibt es bessere Möglichkeiten, einen solchen code hätte unterstützt, dieunion
Ansatz war zumindest etwas praktikabler, zumindest mit C89-ära Interpretationen der aliasing-Regeln.InformationsquelleAutor der Antwort supercat