Supprimer le destructeur de lancement appelé depuis le destructeur


Mircea Baja

Je comprends que les règles actuelles en C ++ disent que:

si un destructeur lance alors que la pile se déroule déjà à cause d'une exception, alors std::terminateest appelé.

En explorant pourquoi les règles sont telles qu'elles sont, je suis tombé sur la situation décrite dans le code ci-dessous.

  1. Le destructeur des Xlancers.

  2. Ysupprime un Xdans son propre destructeur.

  3. Par conséquent, le destructeur des Ylancers.

Ce n'est pas clair pour moi si le fait que les Ylancers (3.) doivent être déclenchés std::terminatepar les règles standard. J'espère qu'il ne devrait pas, et tester contre des gcccourses comme je l'espérais.

Une personne familière avec le jargon juridique standard peut-elle clarifier cela? Devrait (3.) déclencher std::terminateou non?

#include <iostream>

struct X {
  ~X() noexcept(false) {
    std::cout << "Destroying X\n";
    throw std::runtime_error("Exception");
  }
};

struct Y {
   X * x_;

  explicit Y(X * x) : x_{x} { }

  ~Y() noexcept(false) {
    std::cout << "Destroying Y\n";
    delete x_;
  }
};

int main() {
  try {
    Y y(new X());
    std::cout << "Living\n";
  }
  catch (const std::exception & e) {
    std::cout << "Caught " << e.what() << '\n';
  }
}

Avec g ++ version 5.4.0-6ubuntu1 ~ 16.04.9 avec --std=c++17j'obtiens:

Living
Destroying Y
Destroying X
Caught Exception
Fusées1111

La norme dit dans [except.terminate] p1.4 :

  • lorsque la destruction d'un objet pendant le déroulement de la pile se termine par la levée d'une exception, ou

2) se produit parce qu'il yest hors de portée. 1) lève une exception, qui démarre le déroulement de la pile. Pendant le déroulement de la pile, plus précisément lors de la destruction Y- qui est de 2). Il lève une exception, et donc le point est satisfait et std::terminateest appelé.

C'est exactement ce que fait votre code, à l'exception d'un point important: lors du déroulement de la pile . Le déroulement de la pile ne se produit pas à la fin d'une étendue, cela se produit uniquement lorsqu'une exception est levée et sort de la portée actuelle dans laquelle elle a été levée.

Yn'est pas détruit à cause d'une exception. Ajoutez un throw 1;pour voir un appel à l' std::terminateaction.

Ainsi, cette clause ne s'applique pas et votre code est en effet valide.

Articles connexes


Appel du vecteur de threads depuis le destructeur

Chuan Sun Pourquoi ne puis-je pas appeler mon vecteur de threads depuis le destructeur? Existe-t-il une règle pour l'utilisation des destructeurs? void p () { std::cout << "thread running " << std::endl; } class VecThreads // Error: In instantiation of me

Appel de BeginInvoke depuis un destructeur

JonDrnek J'ai du code dans une application WPF qui ressemble à ceci: public class MyTextBox : System.Windows.Controls.TextBox, IDisposable { public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual

Le destructeur de la classe enfant n'est pas appelé

Alexandre Je travaille actuellement sur un jeu en tant que projet pour mon université. Il est réalisé en C++ avec SDL2. J'ai un vecteur qui contient des pointeurs de la classe Enemies, qui est une classe parente abstraite de la Plantclasse. Dans le constructeu

Renvoyer le destructeur de classe

Ciprian Ambrus Je suis étudiant et j'apprends le C ++. Je suis assez bon en C ++, encore des choses «simples» m'empêtrent. J'ai récemment appris des classes, des méthodes, des constructeurs / déconstructeurs, des héritages, des virtuels, etc. J'ai ce code: #in

Le destructeur C ++ n'est pas appelé

MaXL130 J'ai trois classes: Room, Door et World #include <set>; using namespace std; class Door; // Forward declaration class Room { public: Door* door1; Door* door2; Room(){} ~Room() { delete door1; door1 = 0; dele

l'appel cuda échoue dans le destructeur

Bo Li Je suis nouveau dans CUDA et j'ai rencontré un problème lors de l'écriture d'une variable singleton / globale à l'aide de CUDA. Le singleton alloue de la mémoire cuda et essaie de la libérer dans le destructeur. Cependant, le destructeur plante avec cuda