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?

Était-ce utile?

La solution

  

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?

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.

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