8
votes

Objets de classe de comportement étrange à l'intérieur de l'union

salut je voulais savoir les raisons du code suivant xxx

pour le code ci-dessus, il donne une erreur " Erreur C2620: Union" Test ': membre "T1" a constructeur défini constructeur ou non trivial constructeur par défaut " xxx

pour ce qui précède, aucune erreur.

Je voulais connaître les raisons. < / P>

Merci d'avance. :)


3 commentaires

Comme les réponses ont déjà été fournies, je voudrais simplement vous dire que votre premier code a un type de rendement erroné pour le principal. Main () doit toujours renvoyer un "INT" en C / C ++.


Juste pour le record: C ++ 0x disposera d'un support pour les classes avec un constructeur / destructeurs non triviaux à l'intérieur des syndicats.


Également dans la classe Test 1, l'acteur est nommé test au lieu du test 1.


3 Réponses :


9
votes

La norme C ++ place certaines restrictions sur les types de données pouvant être placées à l'intérieur d'une union. Dans 9.5.1, la norme se lit comme suit:

un objet d'un classe avec un constructeur non trivial, un constructeur de copie non triviale, un destructeur non trivial, ou un Opérateur d'affectation de copie non triviale ne peut pas être membre d'une union, ni un tableau de tels objets. Si un syndicat contient un membre de données statique ou un membre d'un type de référence, le programme est mal formé.

Donc, votre programme ne fonctionne pas car vous définissez explicitement un constructeur, et votre objet viole donc la restriction de constructeur non triviale.


0 commentaires

18
votes

Selon la norme C ++ (§9.5.1, citée aussi bien dans d'autres réponses):

Un syndicat peut avoir des fonctions membres (y compris les constructeurs et destructeurs), mais pas des fonctions virtuelles. Une union ne doit pas avoir de classes de base. Une union ne doit pas être utilisée comme classe de base. Un objet d'une classe avec un constructeur non trivial, un constructeur de copie non trivial, un destructeur non trivial ou un opérateur d'affectation de copie non triviale ne peut pas être membre d'un syndicat, ni un éventail de tels objets. Si un syndicat contient un élément de données statique ou un membre d'un type de référence, le programme est mal formé.

I Lié d'abord au Wikipedia Article sur les types de POD qui indique: < / p>

Un type de podage en C ++ est défini comme un type scalaire ou une classe de pod. La classe POD n'a pas d'opérateur d'affectation de copie définie par l'utilisateur, aucun destructeur défini par l'utilisateur, et aucun membre de données non statique qui ne sont pas eux-mêmes des pod. De plus, la classe POD doit être un agrégat, ce qui signifie qu'il n'a pas de constructeurs déclarés par l'utilisateur, aucune donnée non statique privée ni protégée, aucune base et aucune fonction virtuelle. La norme comprend des déclarations sur la manière dont les pod doivent se comporter en C ++.

et

Dans certains contextes, C ++ permet uniquement à des types de pod à utiliser. Par exemple, une union en C ++ ne peut pas contenir une classe comportant des fonctions virtuelles, des constructeurs ou destructeurs non passionnaires . Cette restriction est imposée car le compilateur ne peut pas savoir quel constructeur ni destructeur devrait être appelé à un syndicat.

La première phrase du deuxième paragraphe peut vous faire penser que C ++ permet uniquement aux types de POD de faire partie d'une union. Ce n'est pas exactement le cas car il permet à une classe avec des membres privés de faire partie d'un syndicat: xxx

Le programme ci-dessus compilé avec MSVC ++ imprime: xxx


5 commentaires

@Gregory: ignorer mon commentaire précédent, comme je suis maintenant moins sûr de cela. C'est ainsi que je considère la situation: la norme (en 9.5.1) n'interdit pas explicitement les types de non-POD dans les syndicats, mais plutôt interdire les types qui ont des constructeurs non triviaux / destructeurs / gestionnaires d'affectation. Cette définition se chevauche certainement avec la POD dans une certaine mesure, mais la définition de la POD interdit également les variables des membres privés, ce qui, autant que je sache, ne sont pas exclus des syndicats. Il semble donc que certains non-cosses sont autorisés dans les syndicats. Mais encore une fois, je ne suis pas totalement certain à ce sujet.


En effet, l'Union fonctionne avec des types ayant des variables de membre privé bien que celles ne soient pas considérées comme une pod


@Challes: une classe avec attributs de membre privé et un constructeur trivial est problématique (les membres seraient ininitialisés), donc je ne peux pas vraiment penser à un exemple de monde réel où cela s'appliquerait


@Dribeas: Oui, ce serait étrange. Mais la classe non-POD pourrait toujours avoir des fonctions membres qui utilisent ces variables de membre privé.


Est-ce valide pour C ++ 11? @GregoryPakosz



6
votes

en C ++, les syndicats peuvent ne pas contenir de cours avec des constructeurs (non triviaux) ou des destructeurs. En effet, le compilateur n'a aucun moyen de dire quel constructeur ni destructeur à utiliser lorsqu'une instance syndicale est créée ou détruite.


0 commentaires