2010-06-18 7 views
3

Si j'ai une classe:C++ Union, struct Type membre

class Odp 
{ 
    int i; 
    int b; 
    union 
    { 
     long f; 
     struct 
     { 
       WCHAR* pwszFoo; 
       HRESULT hr; 
     }; 
    }; 

} 

Union signifie que, de toutes les valeurs cotées, il ne peut prendre une de ces valeurs à la fois? Comment cela fonctionne-t-il en termes d'accès à ces variables? Comment accéder directement au hr? Si je règle hr, que se passe-t-il si j'essaie d'accéder à f?

Répondre

7

Ceci est une zone très tendue dans la norme C++ - essentiellement une instance d'union, par la norme ne peut être traitée à la fois comme si elle contenait un membre "actif" - le dernier écrit. Alors:

union U { 
    int a; 
    char c; 
}; 

alors:

U u; 
u.a = 1; 
int n = u.a; 
u.c = 2; 
char c = u.c; 

est OK, mais:

U u; 
u.a = 1; 
char c = u.c; 

est pas. Cependant, il existe de vastes volumes de code existant qui disent que les deux sont OK. et dans aucun ou dans aucun cas une exception ne sera levée pour un accès "invalide". Le langage C++ utilise les exceptions exceptionnellement (!) Avec parcimonie. Fondamentalement, si vous vous trouvez en utilisant des syndicats dans votre code C++ pour traiter tout sauf les bibliothèques C, quelque chose ne va pas.

+0

+1 - mais même pour les bibliothèques C, reinterpret_cast est utilisable à la place d'une union la plupart du temps. –

1

Cela signifie simplement que vous pouvez accéder à la même mémoire que le long ou le struct.

Pour accéder hr:

Odp o1; 
o1.hr; 

lien intéressant: http://www.cplusplus.com/forum/general/18816/

+0

Dans ce cas, la structure n'a pas de nom. Comment y accéder? –

+1

@Rosarch: Techniquement c'est illégal en C. C'est légal en C++, auquel cas les noms sont exposés en tant que membres de 'class Odp'. –

+0

Belle prise @Billy –

1

droit, avec un union les mêmes emplacements de mémoire seront utilisés pour représenter un seul des membres à un moment donné. Donc, si vous avez une instance de l'union et définissez la valeur de hr, vous obtiendrez des ordures si vous essayez alors de lire la valeur de f.

Essayez d'utiliser les éléments suivants pour accéder hr:

union a; 
a.hr = NULL; 
+0

Donc c'est au programmeur de se prémunir contre ça, ou est-ce qu'une exception sera lancée? –

+0

@Rosarch: Ceci est une caractéristique C; C n'a pas d'exceptions. Utilisez les syndicats à vos risques et périls :) –

+0

Aucune exception ne sera levée; il appartient au programmeur de s'assurer qu'il accède au bon membre de l'union. –

3

Chaque fois que vous définissez (écrire) un membre d'un syndicat, vous permettent essentiellement « actif ». Vous êtes seulement autorisé à lire le membre actuellement actif du syndicat. Cela signifie qu'il est de votre responsabilité de vous rappeler quel membre est actif à chaque moment.

La tentative d'accès au membre inactif d'une union entraîne un comportement indéfini. N'oubliez pas que votre code n'est pas valide. C++. Il n'y a pas de "structure anonyme" en C++. Votre membre struct doit avoir un nom. Si votre compilateur l'accepte, c'est juste une extension non standard supportée par votre compilateur spécifique.

+0

Hmm ... Je savais que le résultat serait de retourner des données indéfinies, mais AFAIK l'accès à l'autre membre ne devrait pas causer un comportement indéfini comme l'accès à la cible d'un pointeur nul. –

+3

@Billy ONeal: Oui, il devrait, pour des raisons évidentes. Puisque les types sont généralement non apparentés, l'autre membre (inactif) peut facilement se retrouver avec une représentation de piège. Quelle est la raison principale (et évidente) que le comportement n'est pas défini? – AnT

+2

"représentation de piège" <- Jamais entendu parler de celui-là avant. +1 –

0

Tenter d'accéder à "f" vous donnera un résultat. Il s'agira probablement de la représentation d'un autre membre de l'union en tant que type de données "f", c'est-à-dire que vous lirez probablement le contenu partiel ou entier du "pwszFoo" représenté comme "long" type de données. Le concept général est facile - les membres du syndicat partagent le même emplacement en mémoire.

Questions connexes