#include <iostream> using namespace std; class Y { public: Y(int ) { cout << "Y(int)\n"; } Y(const Y&) { cout << " Y(const Y&)\n"; } }; int main() { Y obj1 = 2; // Line 1 } Output: Y(int)Expected Output: Y(int) Y(const Y&)Question> Based on my understanding, Line 1 will first create a temporary object Y(2), and then assign the temporary object to obj1. Thus, I expect both Y(int) and Y(const Y&) are called. But the output from vs2010 only reports the first one(i.e. Y(int)). Why?
3 Réponses :
Pourquoi? P> blockQuote>
Parce que dans certaines conditions (spécifié par le paragraphe 12.8 / 31 de l'alinéa 12.8 / 31 de la norme C ++ 11), les appels au constructeur de copie ou du constructeur de déplacement peuvent être élus, même si ces fonctions spéciales (ou le destructeur) ont des effets secondaires: P >
Cette élision de copie / déplacement opérations, appelées élision de copie, est autorisée dans les circonstances suivantes (qui peuvent être combinées à Éliminer plusieurs copies): p>
- [...] p>
- Lorsqu'un objet de classe temporaire qui n'a pas été lié à une référence (12.2) serait copié / déplacé à un objet de classe avec le même type CV-non qualifié, l'opération de copie / déplacement peut être omise par construire l'objet temporaire directement dans la cible de la copie omise / déplacement p>
- [...] p> blockQuote>
Ceci est la seule exception à la règle dite " as-si em>", qui contraint normalement le type de transformations (optimisations) qu'un compilateur peut effectuer sur un programme afin de préserver sa comportement observable. p>
avis, que le mécanisme ci-dessus s'appelle copier élision em> - même lorsqu'il est en fait un appel au constructeur de déplacement qui est élu. p>
Ceci s'appelle constructeur à paramètres unique qui est déclaré sans la fonction
Specificatif explicite p>
BlockQuote> Le compilateur est autorisé à élier la copie supplémentaire et utilisez votre est équivalent à p> Initialisation de la copie code> strong> < / a>.
y (int) code> est un constructeur de conversion. c'est
constructeur de conversion code> strong>
. Ce qui signifie p>
Voir la réponse de Stefano pour une discussion ultérieure (Andy's est correcte). Un explicite code> provoquant une erreur signifie qu'ils ne sont nullement équivalents.
L'initialisation de la copie n'est pas équivalente à l'initialisation directe. Le premier est conceptuellement réalisé en construisant un temporaire à partir de l'expression d'initialisation ( 2 code>), puis de construire ou de construire une copie
obj1 code> de ce temporaire. Cependant, le compilateur est autorisé à élier cet appel au constructeur de déplacement ou au constructeur de copie par 12,8 / 31 (voir ma réponse)
Ceci est parce que le constructeur n'a qu'un seul paramètre et que ce n'est pas marqué dans: p> explicite code>, de sorte que le compilateur tourne automatiquement:
explicit Y(int ) {
cout << "Y(int)\n";
}
Le fait que explicite code> provoque une erreur de compilateur signifie qu'il ne tourne pas par magiquement
= 2 code> dans
(2) code>. Tout
explicite code> est empêchant les conversions implicites sur votre type.
"Pour empêcher ce comportement [...] et la compilation échouera dans votre cas." I>