2017-10-18 6 views
1

Disons que je donne les résultats suivants:Quand une fonction membre est-elle hors de portée?

struct Foo 
{ 
    Foo() : bar([&]{ doSomething();}) 
    std::function<void(void)> bar; 
    void doSomething(){}; 
} 

Et permet de dire un fil appelle en permanence l'élément de barre d'une instance Foo alors qu'un autre thread destructs l'instance Foo. Est-il possible qu'un appel à la barre entraîne un appel de fonction invalide puisque le destructeur de Foo est appelé en premier? Est-ce que le destructeur de Foo invalide les appels de fonction membres avant la désallocation?

Editer: Désolé, j'aurais dû être un peu plus spécifique, est-ce que l'appel de doSomething devient indéfini avant que le destructeur de barre ne soit appelé?

+0

Les variables membres existent dans les objets. S'il n'y a pas d'objet, comment la variable membre peut-elle exister? –

+2

Il est de votre responsabilité de vous assurer qu'aucun fil ne détruit un objet alors qu'un autre fil l'utilise ou pourrait l'utiliser. –

+0

C'est d'ailleurs la principale raison pour laquelle un objet ne peut pas synchroniser sa propre destruction. Si vous voulez implémenter des 'demandes de destruction', c'est-à-dire qu'un objet peut être appelé à détruire tout en traitant simultanément d'autres requêtes, ceci doit être synchronisé * extérieurement *, pas par la classe elle-même. – ComicSansMS

Répondre

0

Les fonctions membres restent valides jusqu'à ce que l'objet soit valide. Lorsque l'objet est détruit, la fonction membre est également détruite et l'objet est détruit lorsque le destructeur est appelé. Ainsi, l'appel en destructeur invalide les fonctions membres. Et si vous appelez une fonction membre après la destruction de l'objet entraînera un comportement indéfini. Vous devez donc vous assurer qu'aucune fonction membre n'a été appelée après la destruction de l'objet.

3

Est-il possible qu'un appel à barre entraîne un appel de fonction invalide puisque le destructeur de Foo est appelé en premier?

Oui, sauf si vous vous assurez que cela ne se produit pas.

Le destructeur de Foo invalide-t-il les appels de fonction membres avant la désallocation?

Oui. Toutes les références à cet objet et à ses sous-objets sont invalidées dès que le destructeur est appelé.

Notez que la fonction membre est quelque chose de différent de ce que vous avez. Ce que vous avez est un wrapper de fonction qui est un objet membre. La distinction ne fait cependant aucune différence pour la réponse.

+0

Pour clarifier: * Invalider * signifie ici qu'il n'est plus valide d'exécuter une fonction membre dès que le destructeur démarre. Le langage ne l'applique pas réellement. Il est de votre responsabilité de veiller à ce que cela n'arrive jamais. Si vous ne parvenez pas à le faire correctement, le programme est autorisé à exploser dans votre visage. – ComicSansMS