Maison > développement back-end > C++ > Pourquoi le constructeur de déplacement n'est-il pas appelé dans C 11 lorsque l'élision de copie est activée ?

Pourquoi le constructeur de déplacement n'est-il pas appelé dans C 11 lorsque l'élision de copie est activée ?

DDD
Libérer: 2024-11-06 09:46:02
original
305 Les gens l'ont consulté

Why Is the Move Constructor Not Called in C  11 When Copy Elision Is Enabled?

Constructeur de déplacement C 11 non appelé, constructeur par défaut préféré

Lorsque vous travaillez avec des classes en C, il est prévu que les constructeurs de déplacement soient utilisés pour transfert efficace des ressources. Cependant, dans certains cas, le constructeur par défaut peut être choisi de manière inattendue.

Énoncé du problème

Considérez la classe suivante :

<code class="cpp">class X {
public:
    explicit X(char* c) { cout << "ctor" << endl; init(c); }
    X(X& lv)  { cout << "copy" << endl;  init(lv.c_); }
    X(X&& rv) { cout << "move" << endl;  c_ = rv.c_; rv.c_ = nullptr; }

    const char* c() { return c_; }

private:
    void init(char* c) { c_ = new char[strlen(c) + 1]; strcpy(c_, c); }
    char* c_;
};</code>
Copier après la connexion

Avec l'exemple d'utilisation :

<code class="cpp">X x("test");
cout << x.c() << endl;
X y(x);
cout << y.c() << endl;
X z(X("test"));
cout << z.c() << endl;</code>
Copier après la connexion

Le résultat attendu est :

ctor
test
copy
test
ctor move test
Copier après la connexion

Cependant, la dernière ligne affiche de manière inattendue "ctor" au lieu de "move".

Explication

Selon la norme C 11, les constructeurs de mouvements doivent être appelés dans certaines situations. Dans ce cas, un déplacement devrait se produire lors de la construction de z avec X("test"). Cependant, le constructeur par défaut est appelé à la place.

Ce comportement est dû à l'élision de copie, une technique d'optimisation qui permet au compilateur de construire directement un temporaire dans une cible sans effectuer d'opération de copie ou de déplacement. Cette optimisation s'applique dans les cas où le compilateur détermine que l'opération de copie/déplacement est inutile et peut être supprimée.

Dans le scénario donné, le compilateur considère le X("test") temporaire comme candidat à l'élision de copie, car il est automatiquement créé et détruit au sein de la même expression. Par conséquent, il omet l'opération de déplacement et construit z directement en utilisant les données du temporaire, ce qui entraîne l'appel au constructeur par défaut.

Conclusion

L'élision de copie peut conduire à des erreurs inattendues. comportement lorsque vous travaillez avec des constructeurs de déplacement, car cela peut empêcher le constructeur de déplacement d'être invoqué dans les situations où il est attendu. Les compilateurs peuvent appliquer l'élision de copie en fonction de leurs heuristiques d'optimisation, qui peuvent varier selon les compilateurs et les paramètres d'optimisation. Il est important d'être conscient de l'élision de copie et de son impact potentiel sur le comportement du programme.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal