C ++ constructeur de copie, et copie sémantique temporaires
Question
Pour ce programme
#include <iostream>
using std::cout;
struct C
{
C() { cout << "Default C called!\n"; }
C(const C &rhs) { cout << "CC called!\n"; }
};
const C f()
{
cout << "Entered f()!\n";
return C();
}
int main()
{
C a = f();
C b = a;
return 0;
}
la sortie que je reçois est:
Entered f()!
Default C called!
CC called!
Depuis f()
retourne en valeur, elle doit retourner temporaire. Comme T a = x;
est T a(x);
, ne serait-il appeler le constructeur de copie pour la construction de a
, avec comme argument temporaire passé en?
La solution
Depuis
f()
retourne en valeur, elle doit retourner temporaire. CommeT a = x;
estT a(x);
, ne serait-il appeler le constructeur de copie pour la construction dea
, avec comme argument temporaire passé en?
Consulter la valeur de retour Optimisation. Ceci est activé par défaut. Si vous êtes sur Windows à l'aide MSVC 2005+ vous pouvez utiliser /Od
pour désactiver cette et obtenir le résultat souhaité (ou -fno-elide-constructors
sur GCC). En outre, pour MSVC voir cet article .
12.8 objets de classe copie
15 Lorsque certains critères sont respectés, un la mise en œuvre est autorisé à omettre la construction de copie d'un objet de classe, même si le constructeur de copie et / ou destructeur de l'objet ont latérale effets. Dans ce cas, la la mise en œuvre traite la source et cible de l'opération de copie omis comme simplement deux façons différentes de se référant au même objet, et destruction de l'objet se produit à la plus tardive des moments où les deux objets auraient été détruite sans optimization.115 Cette élision de copie les opérations sont autorisées dans la circonstances suivantes (qui peut être combiné à éliminer plusieurs copies):
- dans une déclaration de retour dans un fonction avec un type de retour de classe, lorsque l'expression est le nom d'un objet automatique non volatile avec le même type cv-non qualifié comme fonction type de retour, la copie opération peut être omise par construction de l'objet automatique directement dans le retour de la fonction valeur - dans une touche d'expression, quand l'opérande est le nom d'un objet automatique non volatile, la opération de copie de l'opérande au objet exception (15.1) peut être omis en construisant l'objet automatique directement dans l'objet d'exception
- quand un objet de classe temporaire qui a pas été lié à une référence (12.2) seraient copiés sur un objet de classe le même type de cv-non qualifié, la copie opération peut être omise par la construction de l'objet temporaire directement dans la cible de la copie omis
- lorsque la exception-déclaration d'une exception gestionnaire (article 15) déclare un objet du même type (à l'exception de cv-qualification) comme l'exception objet (15.1), l'opération de copie être omis en traitant la exception-déclaration comme un alias pour l'objet d'exception si le sens de le programme sera inchangé à l'exception pour l'exécution des constructeurs et destructeurs pour l'objet déclaré par l'exception-déclaration.
Note: Non souligné
Autres conseils
Ceci est un exemple de Valeur de retour Optimisation (RVO) caractéristiques qui prend en charge votre compilateur.
Un constructeur de copie peut-être pas être appelé lorsque vous revenez en valeur.
option Utiliser -fno-elide-constructors
sur GCC pour activer cette fonction.
Je crois qu'il appelle optimisation de la valeur de retour .
Je suppose que lors du retour de f()
C
objet de l'objet est allouée dans l'espace de pile de la méthode appelante donc pas de copie est nécessaire pour initialiser C a
. Ceci est votre default C called
.
C b = a
Cela provoque un constructeur de copie donc votre CC called
.
BTW, l'exemple sur le wiki ressemble assez similaire à votre code.