Je pensais qu'en C++, si un constructeur lance une exception, le destructeur de cette "partiellement construit" la classe n'est pas appelé.
Mais il semble qu'il n'est plus vrai en C++11
C'est toujours vrai. Rien n'a changé depuis C++03 (pour une certaine valeur de rien ;-) )
Qu'avez-vous pensé est toujours vrai, mais il n'est pas partiellement construit de l'objet lorsque l'exception est levée.
Le C++03 TC1 standard dit (l'emphase est mienne):
Un objet qui est partiellement construit ou partiellement détruites aura destructeurs exécutée pour tous les de son entièrement construite sous-objets, qui est, pour les sous-objets pour lesquels le constructeur a terminé l'exécution, et le destructeur n'a pas encore commencé l'exécution.
c'est à dire un objet qui a terminé son constructeur détruits par l'exécution du destructeur. C'est une bonne règle simple.
Fondamentalement la même règle s'applique en C++11: dès qu' X(int)
a retourné, l'objet du "constructeur a terminé l'exécution" de sorte qu'il est entièrement construit, et donc de son destructeur sera exécuté au moment opportun (quand elle est hors de portée ou une exception est levée lors d'un stade ultérieur de ses travaux de construction.) C'est toujours la même règle, dans l'essence.
La délégation corps du constructeur s'exécute après l'autre constructeur et peuvent faire du travail supplémentaire, mais cela ne change pas le fait que l'objet de la construction est terminée, de sorte qu'il est entièrement construit. La délégation constructeur est analogue à une classe dérivée de' constructeur, qui permet d'exécuter du code après une classe de base constructeur de finitions. Dans un certain sens, vous pouvez envisager votre exemple, comme ceci:
class X
{
public:
X(int a)
{
cout << "X::X(" << a << ")" << endl;
}
~X()
{
cout << "X destructor" << endl;
}
};
class X_delegating : X
{
public:
X_delegating() : X(10)
{
throw runtime_error("Exception thrown in X::X()");
}
};
ce n'est pas vraiment comme ça, il n'y a qu'un seul type, mais il est analogue dans la mesure où la X(int)
constructeur, le code supplémentaire dans le déléguant constructeur s'exécute, et si qui lève l' X
"classe de base" (qui n'est pas vraiment une classe de base) est détruit.