Selon Herb Sutter le code ci-dessous ne compilerait pas. Voir ce site http://www.gotw.ca/gotw/066.htm d'où j'ai extrait le texte suivant, en ce qui concerne function-try-blocks
:Selon un auteur averti de la communauté C++, le code ci-dessous ne doit pas être compilé. Il a tort?
Vers Certains Morals
Soit dit en passant, cela signifie aussi que la seule (répéter seulement) utilisation possible pour un constructeur function-try-block est de traduire une exception levée à partir d'un sous-objet de base ou de membre. C'est Morale # 1. Ensuite, Moral # 2 dit que destructeur fonction-try-blocs sont entièrement usele--
"--Mais attendez!" J'entends quelqu'un interrompre au milieu de la pièce. "Je ne suis pas d'accord avec Moral 1. Je peux penser à une autre utilisation possible pour constructor function-try-blocks, à savoir pour libérer les ressources allouées en la liste des initialiseurs ou dans le corps du constructeur!"
Désolé, non. Après tout, n'oubliez pas qu'une fois que vous entrez dans votre constructeur, les variables locales dans le corps du constructeur sont également hors de portée, et vous avez la garantie qu'aucun sous-objet de base ou objet membre n'existe plus, point. Vous ne pouvez même pas faire référence à leurs noms. Soit les parties de votre objet n'ont jamais été construites, soit celles qui ont été construites ont déjà été détruites. Donc, vous ne pouvez pas nettoyer tout ce qui repose sur en référence à une base ou un membre de la classe (et de toute façon, c'est ce que les destructeurs de base et membres sont pour, non?).
En supposant cette citation, le code suivant ne devrait pas compiler, comme l'objet cat
a déjà été détruite au moment où le processus se heurte à la clause catch
. Mais c'est le cas, au moins avec VSC2008.
class Cat
{
public:
Cat() { cout << "Cat()" << endl; }
~Cat() { cout << "~Cat()" << endl; }
};
class Dog
{
public:
Dog() { cout << "Dog()" << endl; throw 1; }
~Dog() { cout << "~Dog()" << endl; }
};
class UseResources
{
class Cat *cat;
class Dog dog;
public:
UseResources();
~UseResources() { delete cat; cat = NULL; cout << "~UseResources()" << endl; }
};
UseResources::UseResources() try : cat(new Cat), dog() { cout << "UseResources()" << endl; } catch(...)
{
delete cat;
throw;
}
+1 pour citer la partie pertinente de la norme. –