2017-08-25 15 views
1

Lors de l'exécution du code suivant sur gcc 8 (https://wandbox.org/, avec "g ++ prog.cc -Wall -Wextra std = C++ 1z"):élément de référence de liaison ++ C au paramètre de constructeur

#include <iostream> 

class B{ 
public: 
    B(): copy(false){ std::cout << "B-constructed" << std::endl;} 
    B(const B& b): copy(true){ std::cout << "B-copy-constructed" << std::endl; } 
    ~B(){ std::cout << (copy?"B-destructed":"B-(copy)-destructed") << std::endl;} 

    bool copy; 
}; 

class A{ 
public: 
    A(B b): bref(b){std::cout << "A-constructed" << std::endl;} 
    ~A() {std::cout << "A-destructed" << std::endl;} 
    B &bref; 
}; 


void f(){ 
    B b; 
    A a(b); 

    std::cout << "f over" << std::endl; 
} 

int main() 
{ 
    f(); 

    std::cout << "main over" << std::endl; 
    return 0; 
} 

ce qui suit la sortie est cédée:

B-constructed 
B-copy-constructed 
A-constructed 
B-destructed 
f over 
A-destructed 
B-(copy)-destructed 
main over 

L'ordre de destruction des objets semble inhabituel. C'est comme si la durée de vie du paramètre du constructeur était étendue. Est-ce que la norme dit quoi que ce soit à propos de la référence des membres aux paramètres constructeurs?

Je ne pense pas que cette citation de la norme applique, comme le paramètre est un objet temporaire (mais je ne sais pas à la définition d'une « expression temporaire »):

Une expression temporaire lié à un membre de référence dans un mem-initializer est mal formé. [Exemple:

struct A {

A(): v (42) {} // erreur

const int & v;

};

exemple -end]

+1

Vous mélangé les chaînes dans '~ B': si elle est une copie, dire qu'il est normalement détruit, sinon, dire qu'il est la copie destructed –

+0

Alors, quelle est la question alors? Que pensez-vous qui ne va pas avec l'ordre de construction/destruction, après que ce soit réglé? –

+0

Maintenant, la commande semble bien. Cependant, la question qui reste est de savoir si la norme dit quoi que ce soit sur la liaison des références membres aux paramètres constructeurs. – user42768

Répondre

1

Votre destructor a une erreur logique, puisque l'impression qu'une copie est quand copy destructed est faux.

Modifier ceci:

~B(){ std::cout << (copy?"B-destructed":"B-(copy)-destructed") << std::endl;} 

à ceci:

~B(){ std::cout << (copy?"B-(copy)-destructed":"B-destructed") << std::endl;} 

qui sort maintenant:

B-constructed 
B-copy-constructed 
A-constructed 
B-(copy)-destructed 
f over 
A-destructed 
B-destructed 
main over 

agréable et claire (Order of member constructor and destructor calls). Est-ce que le standard dit quelque chose au sujet des références de membre de liaison aux paramètres de constructeur?


De même, avant la durée de vie d'un objet a commencé, mais après le stockage que l'objet occuperez a été attribué ou, après la durée de vie d'un objet a pris fin et avant le stockage que l'objet occupé est réutilisé ou libéré, toute valeur de référence faisant référence à l'objet original peut être utilisée mais de manière limitée. Pour un objet en cours de construction ou de destruction, voir [class.cdtor]. Sinon, un tel glissement renvoie à la mémoire allouée ([basic.stc.dynamic.deallocation]) et l'utilisation des propriétés du glglue qui ne dépendent pas de sa valeur est bien définie.

Source

+0

Je m'excuse pour mon erreur. Oui, la commande semble maintenant correcte. Cependant, la norme mentionne-t-elle quelque chose au sujet des références de membre de liaison aux paramètres de constructeur? – user42768

+0

Bien sûr, pas de problème. J'ai corrigé ma question à cause du commentaire reçu de @king_nak avant de voir ta réponse. – user42768

+0

J'ai trouvé ceci: http://eel.is/c++draft/basic.life#7. Je pense que cela explique ce qui se passe lorsqu'on référence un objet dont la vie s'est terminée. – user42768