2017-03-07 2 views
1

J'ai écrit le code suivant dans lequel une fonction renvoie une référence à un membre. La valeur de retour est stockée de 2 façons pendant 2 appels différents à la fonction:Le renvoi d'une référence à partir d'une fonction entraîne-t-il la création d'un nouvel objet temporaire lorsque 'auto' est utilisé?

  1. Une référence automatique est utilisée pour stocker la valeur de retour. Comme je le supposais à juste titre, les adresses de l'objet auquel la référence est renvoyée et l'adresse de la référence automatique qui stocke la valeur de retour sont les mêmes, comme il ressort de la sortie. 'Auto' est utilisé pour stocker la valeur de retour. Je supposais, la variable automatique devrait entraîner un nouvel objet créé sur la pile qui contient la copie des valeurs de l'objet à laquelle la référence a été renvoyée par la fonction. Je pouvais voir que les adresses de l'auto et l'objet réel sont en effet différents. Cependant, je n'ai pas vu le constructeur s'appeler pour l'objet créé en utilisant auto. Un objet est-il en effet créé dans ce cas?

// code

#include <iostream> 
    using namespace std; 

    class c1 { 
    private: 
     int i; 

    public: 
     c1() { 
      cout << "c1()" << endl; 
      i = 10; 
     } 

    }; 

    class c2 { 
    private: 
     c1 mc1; 

    public: 
     c2() { 
      cout << "c2()" << endl; 
     } 

     c1& getmc1() { 
      cout << "address of mc1 : " << &mc1 << endl; 
      return mc1; 
     } 
    }; 

    int main() { 
     c2 c; 
     auto& c1_1 = c.getmc1(); 
     cout << "address of c1_1 : " << &c1_1 << endl; 

     c2 c_2; 
     auto c1_2 = c_2.getmc1(); 
     cout << "address of c1_1 : " << &c1_1 << endl; 

     return 0; 
    } 


//Output 
c1() 
c2() 
address of mc1 : 00AFF82C --> Same as below address, expected 
address of c1_1 : 00AFF82C 
c1() 
c2() 
address of mc1 : 00AFF814 --> Different from below address, expected 
address of c1_1 : 00AFF82C --> why c1() constructor is not invoked ? 

Modifier

@NathanOliver, @Tali,

Merci de remarquer sur le constrcutor copie. J'en ai ajouté un, et j'ai pu voir la bonne sortie. Je suis un débutant en C++. J'ai manqué le point que le compilateur génère un constructeur de copie implicite.

Voici le programme mis à jour.

#include <iostream> 
using namespace std; 

class c1 { 
private: 
    int i; 

public: 
    c1() { 
     cout << "c1()" << endl; 
     i = 10; 
    } 

    c1(c1 &c) { 
     cout << "c1(c1 &c)" << endl; 
     i = c.i; 
    } 

}; 

class c2 { 
private: 
    c1 mc1; 

public: 
    c2() { 
     cout << "c2()" << endl; 
    } 

    c1& getmc1() { 
     cout << "address of mc1 : " << &mc1 << endl; 
     return mc1; 
    } 
}; 

int main() { 
    // your code goes here 
    c2 c; 
    auto& c1_1 = c.getmc1(); 
    cout << "address of c1_1 : " << &c1_1 << endl; 

    c2 c_2; 
    auto c1_2 = c_2.getmc1(); 
    cout << "address of c1_1 : " << &c1_2 << endl; 

    return 0; 
} 

Sortie:

c1() 
c2() 
address of mc1 : 010FFE18 
address of c1_1 : 010FFE18 
c1() 
c2() 
address of mc1 : 010FFE00 
c1(c1 &c) 
address of c1_1 : 010FFDF4 
+0

Vous avez oublié le constructeur de la copie. – NathanOliver

+1

Quel est le but de la duplique 'cout << ...' pour votre deuxième cas? Vous récupérez quelque chose pour 'c1_2', puis vous l'ignorez et vous renvoyez l'adresse de' c1_1'. – WhozCraig

+0

@ WhozCraig, Merci de m'avoir signalé. C'était un cas classique de faute de frappe :). J'ai corrigé le programme comme dans le message ci-dessous. L'ajout d'un constructeur de copie a résolu le problème. – codeseeker

Répondre

2

Oui le nouvel objet est construit, mais pas en utilisant votre c1::c1(). Ces copies d'objets sont effectuées à l'aide du constructeur de copie c1::c1(const c1 &).

Dans votre exemple, vous ne fournissez pas de constructeur de copie afin que le compilateur en génère implicitement un.