44 votes

appel explicite du destructeur

Je comprends que, dans la plupart des cas, nous ne devrions pas appeler un destructeur explicitement [s'il vous Plaît corrigez-moi si je me trompe ici]. Cependant, j'ai vu un exemple à partir de C++11 Standard N3485 Section 13.4.5 arguments de Modèle:

Un destructeur explicite appel (12.4) pour un objet qui a un type qui est un modèle de classe spécialisation peut spécifier explicitement le modèle-arguments. [ Exemple:

template<class T> struct A {
   ~A();
};

void f(A<int>* p, A<int>* q) {
    p->A<int>::~A(); // OK: destructor call
    q->A<int>::~A<int>(); // OK: destructor call
} -end example ]

Il me semble que nous pouvons appeler le destructeur de manière explicite dans ce cas, pourriez-vous m'expliquer pourquoi? Ce qui est le cas pour ceux destructeur d'appel de dire dans cet exemple? Pourquoi sont-ils raisonnables?

Une autre question:

Quels sont les cas que nous pouvons appeler les destructeurs explicitement d'ailleurs lorsque nous mettons en oeuvre placement delete?

Je vous remercie.

EDIT: j'ai trouvé à partir de C++ FAQ que nous ne devrions pas appeler explicitement un destructeur sur une variable locale.

31voto

Mike Seymour Points 130519

Il me semble que nous pouvons appeler le destructeur de manière explicite dans ce cas, pourriez-vous m'expliquer pourquoi?

Voulez-vous dire pourquoi pouvons-nous? Parce que la langue permet destructeur explicite appels sur n'importe quel objet. Comme vous le dites, on donne en général un comportement indéterminé puisque la plupart des objets seront détruits de toute autre manière, et c'est un comportement indéterminé de détruire quoi que ce soit deux fois (ou plus généralement d'accéder, après la destruction). Mais cela signifie simplement que vous ne devez pas le faire, non pas que la langue va vous empêcher de le faire.

Ou voulez-vous dire pourquoi voudrions-nous? Parce que vous détruisez un objet créé par le placement de nouvelles.

Ce qui est le cas pour ceux destructeur d'appel de dire dans cet exemple?

Ils ont tous deux veulent dire la même chose, et sont équivalentes à l' p->~A(); ils appellent le destructeur de l'objet. L'exemple démontre que vous pouvez fournir des arguments de modèle, si vous le souhaitez. Je ne suis pas sûr pourquoi vous voulez.

Quels sont les cas que nous pouvons appeler les destructeurs explicitement à part le placement supprimer?

Je pense que vous êtes autorisé à appeler un trivial destructeur (celui qui ne fait rien) chaque fois que vous le souhaitez; mais il n'y a pas de point. Je pense que de détruire quelque chose de créé avec la mise en place de nouvelles est la seule raison légitime de le faire.

26voto

Sean Middleditch Points 1050

Il me semble que nous pouvons appeler le destructeur de manière explicite dans ce cas, pourriez-vous m'expliquer pourquoi?

Parce que c'est permis par la langue pour être en mesure d'appeler le destructeur de n'importe quel objet chaque fois que vous voulez (en supposant que vous avez accès, par exemple, il n'est pas privé destructeur).

Ce qui est le cas pour ceux destructeur d'appel de dire dans cet exemple?

Il vient appelle le destructeur. Logiquement, cela signifie que l'objet est détruit et devraient être considérés comme des déchets à partir de ce moment et ne doit pas être déréférencé ou utilisé. Techniquement, cela signifie que l'objet est dans quel état le destructeur laisse au, qui, pour certains objets peuvent être identiques à défaut de construction (mais vous ne devez jamais compter sur qui).

Pourquoi sont-ils raisonnables?

Parfois, vous avez besoin pour détruire les objets sans relâcher leur mémoire. Ce qui se passe dans beaucoup de classe comme variante tout, diverses script de liaison et de réflexion, certains singleton implémentations, etc.

Par exemple, vous pouvez utiliser std::aligned_storage d'allouer un tampon pour un objet, puis utilisez le placement de nouveaux de construire un objet dans la mémoire tampon. Vous ne pouvez pas appeler delete sur cet objet depuis qui permettra à la fois d'appeler le destructeur et essayer de libérer de la mémoire de sauvegarde. Vous devez appeler explicitement le destructeur dans ce cas de bien détruire l'objet.

Quels sont les cas que nous pouvons appeler les destructeurs explicitement à part le placement supprimer?

Il n'y a pas une telle chose comme "placement supprimer", autre que celle d'un opérateur de placement de nouvelles (et tous les appels à des delete sera implicitement appeler le destructeur à l'exception de ceux que le compilateur appelle de l'échec de la construction, par exemple, votre placement supprimer " notion).

Un exemple que j'ai donné ci-dessus. Un autre exemple est - std::vector. Vous pouvez appeler des fonctions de membre comme pop_back(). Ce besoin de détruire le dernier élément du vecteur, mais il ne peut pas utiliser delete depuis la mémoire de sauvegarde de l'objet fait partie d'une plus grande mémoire tampon qui doivent être gérés séparément. Il en va de même pour de nombreux autres conteneurs, telles que l'ouverture d'adressage de tables de hachage, deque, et ainsi de suite. Ceci est un exemple de l'endroit où vous voulez les utiliser l' template typename afin d'appeler le destructeur de manière explicite.

C'est une fonctionnalité que l'utilisateur d'une bibliothèque est très rarement besoin mais le réalisateur d'une bibliothèque bas niveau comme le TSL, ou même certains cadres ont besoin d'utiliser ici et là.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X