Variable de référence dans la définition de la classe
Je suis en train d'apprendre le C++, et j'ai lu que toutes les références doivent être initialisées lors de la déclaration,
et il y a peut être pas de "non initialisé "références". Mais que faire si la variable de référence est un membre de la classe?
class test
{
int &k;
};
int main()
{
test *abc = new test;
}
Ce programme compile et s'exécute normalement (en g++, pas de mises en garde). Cependant, abc->k
est une référence, mais qu'est-ce initialisé? Ou, est-il un "non initialisé " de référence" d'une certaine sorte, ou quelque chose d'autre?
Avez-vous essayé avec tous les avertissements activé?
Et serait-il de donner un avertissement si
Et serait-il de donner un avertissement si
k
a été réellement utilisé?OriginalL'auteur ManRow | 2011-02-19
Vous devez vous connecter pour publier un commentaire.
Le programme est mal formé, car il construit une classe qui ne parvient pas à initialiser un non-membre statique de l'entité de référence type.
Je crois que gcc ne compilateur, mais je n'ai reçu l'avertissement "non-statique de référence ‘int& test::k’ dans la classe sans constructeur".
test
est un non-POD-type struct, car il contient un membre de référence. (9 [classe] /4)new test
par défaut initialise le allouée dynamiquement classe. (5.3.4 [expr.nouveau] /15)À défaut d'initialisation de un objet de type
test
moyens de faire appel à la déclarées implicitement et de manière implicite par défaut définis par le constructeur. (8.5 [dcl.init] /5)Le définit implicitement le constructeur par défaut est l'équivalent d'un constructeur par défaut avec un vide mem-initialisé-liste et un vide corps de la fonction. (12.1 [classe.ctor] /7)
De plus:
Si une entité n'est pas le nom de mem-initialiseur-liste et le membre n'est pas de type de classe [avec d'autres restrictions] ensuite, l'entité n'est pas initialisé.
Merci beaucoup d'avoir signalé le bug dans mon post précédent. J'ai remplacé mon downvote avec un upvote. J'ai besoin d'apprendre à lire la spec plus attentivement à l'avenir!
Pas de soucis, j'ai été à l'origine de mal, je suis juste plus rapide pour corriger mon erreur.
Ce qui est assez intéressant (pour moi, au moins), tout simplement parce que
int &k;
est "de gauche " non initialisé" (vaguement parler, ne signifie pas qu'il peut devenir "initialisé" aprèstest *abc = new test;
. Donc, je suppose que ce n'est pas juste "non initialisé", mais aussi permanence uninitializ-mesure!OriginalL'auteur CB Bailey
J'ai un doute sur la façon de référence est en cours d'initialisation. Lorsque la trame de pile pour la ctr est pris hors de la pile, la référence ne sera plus valide.
OriginalL'auteur Barry
Code réellement l'habitude de compiler sur Visual C++. En général, il est préférable de laisser aussi peu de chance que possible. Vous devez initialiser référence des membres à l'aide d'un initialiser la liste dans le constructeur:
si VC++ rejette ce code, puis il se comporte correctement, et G++ est un être non-conforme. Les deux compilateurs sont généralement assez bon, mais comme @Cody dit, ils ont également tous deux ont des domaines où ils tombent.
Un avertissement est assez d'un diagnostic. En dépit de l'UB, il n'y a pas de problème d'exécution du programme de test, car il n'est pas fait à l'aide de la référence non valide. Nous savons tous que "semble fonctionner", est une commune et méchant effet de comportement indéfini.
Je doute fort de liaison
k
à un paramètre qui va mourir immédiatement après le constructeur a fini est une bonne idée 🙂Juste qu'il est mal formé, désolé, mais le compilateur peut toujours si il se sent comme (après l'émission du diagnostic). Si c'était UB le compilateur n'est pas nécessaire de le détecter. Voyant que la référence n'est pas initialisé n'est pas trop dur. 🙂
OriginalL'auteur Jimmy