523 votes

Ce que copie elision et optimisation de la valeur de retour ?

Qu'est-ce que la copie élision? Qu'est-ce que (nom) valeur de retour d'optimisation? Que font-ils impliquent?

Dans quelles situations peuvent-ils se produire? Quelles sont les limites?

362voto

Luchian Grigore Points 136646

Introduction

Pour une vue d'ensemble technique de sauter à cette réponse.

Pour les cas fréquents où la copie élision se produit - passer à cette réponse.

Copie élision est une optimisation de la mise en œuvre par la plupart des compilateurs pour empêcher les autres (potentiellement coûteux) des copies dans certaines situations. Il fait le retour par valeur ou par la valeur réalisable dans la pratique (des restrictions s'appliquent).

C'est la seule forme de l'optimisation de la élude (ha!) la comme-si la règle - copie élision peut être appliquée même si la copie/déplacement de l'objet a des effets secondaires.

L'exemple suivant provient de Wikipedia:

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};

C f() {
  return C();
}

int main() {
  std::cout << "Hello World!\n";
  C obj = f();
}

Selon le compilateur et les paramètres, les réalisations suivantes sont valides:

Bonjour Tout Le Monde!
Une copie a été faite.
Une copie a été faite.


Bonjour Tout Le Monde!
Une copie a été faite.


Bonjour Tout Le Monde!

Cela signifie également moins d'objets peuvent être créés, afin que vous aussi ne peut pas compter sur un nombre spécifique de destructeurs d'être appelé. Vous ne devriez pas avoir de critique de la logique à l'intérieur de copier/déplacer-constructeurs ou destructeurs, que vous ne pouvez pas compter sur eux d'être appelé.

129voto

Luchian Grigore Points 136646

Les formes courantes de copie élision

Pour une vue d'ensemble technique de sauter à cette réponse.

Pour moins de vue technique et introduction - passer à cette réponse.

(Nommé) de la valeur de Retour de l'optimisation est une forme courante de copie élision. Il se réfère à la situation où un objet retourné par la valeur à partir d'une méthode a sa copie élidés. L'exemple énoncées dans la norme illustre nommé valeur de retour d'optimisation, puisque l'objet est nommé.

class Thing {
public:
  Thing();
  ~Thing();
  Thing(const Thing&);
};
Thing f() {
  Thing t;
  return t;
}
Thing t2 = f();

Régulier de la valeur de retour d'optimisation se produit lorsqu'un temporaire est retourné:

class Thing {
public:
  Thing();
  ~Thing();
  Thing(const Thing&);
};
Thing f() {
  return Thing();
}
Thing t2 = f();

D'autres lieux communs où copier élision prend place, c'est quand un temporaire est passé par valeur:

class Thing {
public:
  Thing();
  ~Thing();
  Thing(const Thing&);
};
void foo(Thing t);

foo(Thing());

ou lorsqu'une exception est levée et l'a attrapé par valeur:

struct Thing{
  Thing();
  Thing(const Thing&);
};

void foo() {
  Thing c;
  throw Thing;
}

int main() {
  try {
    foo();
  }
  catch(Thing c) {  
  }             
}

Limitations communes de copie élision sont:

  • plusieurs points de retour
  • conditionnel d'initialisation

La plupart de qualité commerciale des compilateurs de soutien copie élision & (N)RVO (en fonction des paramètres d'optimisation).

122voto

Luchian Grigore Points 136646

La norme de référence

Pour moins de vue technique et introduction - passer à cette réponse.

Pour les cas fréquents où la copie élision se produit - passer à cette réponse.

Copie élision est défini dans la norme:

12.8 la Copie et le déplacement des objets de la classe [classe.copier]

comme

31) Lorsque certains critères sont respectés, une mise en œuvre est permis d'omettre de le copier/déplacer construction d'une classe objet, même si le copier/déplacer constructeur et/ou le destructeur de l'objet ont des effets secondaires. Dans de tels cas, la mise en œuvre traite de la source et de la cible de l'omis de copier/déplacer des fonctionnement que simplement deux manières de se référer au même objet, et la destruction de cet objet se produit au plus tard à la fois lorsque les deux objets ont été détruits sans l'optimisation.123 Cette élision de copier/déplacer opérations, appelées copie élision, est autorisé dans les circonstances suivantes (qui peuvent être combinées pour éliminer plusieurs copies):

- dans une instruction return dans une fonction avec une classe de type de retour, lorsque l'expression est le nom d'un non-volatile automatique d'objets (autre qu'une fonction ou catch-clause de paramètre) avec le même cvunqualified type que le type de retour de fonction, le copier/déplacer opération peut être omis, par la construction de l'automatique des objets directement dans la fonction de valeur de retour

- dans un jet d'expression, lorsque l'opérande est le nom d'un non-volatile automatique d'objets (autres que les fonction ou catch-clause de paramètre) dont la portée ne s'étend pas au-delà de la fin de l'intime en joignant essayez-bloc (si il y en a un), le copier/déplacer le fonctionnement de l'opérande à l'exception objet (15.1) peut être omis par la construction automatique de l'objet directement dans l'objet de l'exception

- lorsqu'un temporaire de la classe de l'objet qui n'a pas été lié à une référence (12.2) serait copié/déplacé pour un objet de classe avec le même cv-non qualifiés de type, le copier/déplacer opération peut être omis par la construction de l'objet temporaire directement dans la cible de l'omis de copier/déplacer

- lorsque l'exception-la déclaration d'un gestionnaire d'exception (article 15) déclare un objet de même type (sauf pour le cv-qualification) que l'objet de l'exception (15.1), le copier/déplacer opération peut être omis par le traitement de l'exception-déclaration comme un alias pour l'objet de l'exception si le sens du programme sera inchangé, sauf pour l'exécution de constructeurs et destructeurs pour l'objet déclaré par l'exception-déclaration.

123) Parce qu'un objet est détruit au lieu de deux, et un copier/déplacer constructeur n'est pas exécuté, il est toujours une objet détruit pour chacun construit.

L'exemple donné est:

class Thing {
public:
  Thing();
  ~Thing();
  Thing(const Thing&);
};
Thing f() {
  Thing t;
  return t;
}
Thing t2 = f();

et d'expliquer:

Ici, les critères d'élision peuvent être combinés pour éliminer les deux appels au constructeur de copie de la classe Thing: la copie du ou des locaux automatique des objets t dans l'objet temporaire pour la valeur de retour de la fonction f() et la copie de l'objet temporaire d'objet t2. Effectivement, la construction de l'objet local t peut être considéré comme directement de l'initialisation de l'objet global t2, et que l'objet de la destruction se fera au programme à la sortie. L'ajout d'un constructeur de déplacement de Chose a le même effet, mais c'est le mouvement de construction de l' objet temporaire pour t2 qui est élidée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X