Question

Bonjour, tout le monde!

Examiner mon propre code, je suis venu à cette ligne intéressante:

const CString &refStr = ( CheckCondition() ) ? _T("foo") : _T("bar");

Maintenant, je suis tout à fait à perte, et ne peut pas comprendre pourquoi il est légal. Pour autant que je comprends, la référence const doit être initialisé, que ce soit avec la valeur r ou l valeur. références non initialisées ne peuvent pas exister. Mais ()? opérateur exécute une fonction CheckCondition () avant qu'il attribue une valeur à la référence. Je vois maintenant que tout CheckCondition () est exécuté, il existe refStr, mais toujours pas initialisé. Que se passerait-il si CheckCondition () lancera une exception, ou passer le contrôle avec une instruction goto? Est-il laisser la référence non initialisée ou suis-je manque quelque chose?

Était-ce utile?

La solution

exemple Simpler: const int x = foo();

Cette constante a trop à initialiser, et que foo() doit être appelée. Cela se produit dans l'ordre nécessaire. X entre en existance que lorsque revient foo

Pour répondre à vos questions supplémentaires: Si foo() serait throw, l'exception sera pris par un catch() quelque part. Le bloc try{} pour cette catch() entouré const int x = foo(); évidemment. Par conséquent const int x est déjà hors de portée, et il est hors de propos qu'il n'a jamais eu une valeur. Et s'il n'y a pas catch à l'exception, votre programme (y compris const int x) est parti.

C ++ n'a pas de hasard de goto. Ils peuvent sauter à l'intérieur foo() mais cela n'a pas d'importance; foo() doit encore revenir.

Autres conseils

Il vous manque quelque chose - il est tout à code juridique, et en fait ce code est l'une des meilleures utilisations et les plus communes de l'opérateur conditionnel. Il est toujours une erreur de penser que le compilateur doit en interne faire des choses dans le même ordre que le code est aménagé sur la page - il est parfaitement libre d'évaluer l'opérateur conditionnel (ce qui est justv une autre expression), puis utiliser le résultat effectuer l'initialisation.

En ce qui concerne un goto, il n'y a pas moyen d'utiliser l'un dans une initialisation. Et si une exception est levée, la référence est réputé ne jamais avoir été créé en premier lieu.

  

références non initialisées ne peuvent pas exister.

choses drôles Malheureusement peuvent être faites lors de l'initialisation. Vous auriez pu également écrit

const int& a = foobar(a) ? 1 : 2;

ou la question

const int& a = a;

Je suppose que le produit du compilateur de gauche à droite, un est en effet portée sur le côté droit, alors techniquement vous devriez pouvoir l'utiliser au mieux, il peut mettre en garde:

"ComeauTest.c", ligne 9: avertissement: variable "a" est utilisé avant sa valeur est

  const int& a = foobar(a) ? 1 : 2;
                        ^

Bien sûr cela ne peut entraîner un comportement non défini comme l'utilisation une variable non initialisée.

Votre exemple est très bien, puisque vous n'utilisez pas la référence avant qu'il ait été initialisé.

  

Je vois maintenant que tout CheckCondition () est exécuté, il existe refStr, mais toujours pas initialisé.

D'un point de vue de l'avocat de la langue, cela est faux. Lors de l'initialisation, refStr n'existe pas encore. Je suppose que votre débogueur visuel vous donne des conseils trompeurs.

Si le code dans l'initialisation conduit à une condition d'erreur, refStr n'existera pas, et ne sera jamais existé.

Ceci est tout à fait légal. Ou bien ce termine avec succès et la référence est lié à un objet valide ou une exception est levée et le contrôle est transféré en dehors du bloc et la référence n'est plus portée si Noone prend soin de plus.

Une exception vous amènera à un endroit où refStr est pas accessible et vous ne pouvez pas aller à un endroit où il est de là. Un goto ne sera pas en mesure de sortir de CheckCondition () si elle est une fonction, et vous ne serez pas en mesure d'utiliser un goto si elle est une macro. Un longjmp () aura le même effet qu'une exception. Vous allez à un endroit où refStr n'est pas accessible

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top