Согласно Хербу Саттеру, приведенный ниже код не будет компилироваться.См. Этот сайт http://www.gotw.ca/gotw/066.htm, откуда я извлек следующий текст, касающийся function-try-blocks
:
Навстречу морали
Кстати,это также означает, что единственное (только повторное) возможное использование для конструктора function-try-block - это преобразование исключения, выданного из подобъекта base или member.Это Мораль № 1.Далее, Мораль # 2 говорит, что функциональные блоки-деструкторы полностью используются -
"- Но подождите!"Я слышу, как кто-то прерывает с середины комнаты.«Я не согласен с Моралем # 1. Я могу подумать о другом возможном использовании для функции-блока-конструктора, а именно, для освобождения ресурсов, выделенных в списке инициализатора или в теле конструктора!»
Извините,Нету.В конце концов, помните, что как только вы попадаете в обработчик try-block вашего конструктора, любые локальные переменные в теле конструктора также уже находятся вне области видимости, и вам гарантировано, что никаких базовых подобъектов или объектов-членов больше не существует, точка.Вы даже не можете ссылаться на их имена.Либо части вашего объекта никогда не были построены, либо те, которые были построены, уже были уничтожены.Таким образом, вы не можете очистить что-либо, что основано на обращении к базе или члену класса (и в любом случае для этого нужны деструкторы базы и члена, верно?).
Предполагая, что этов кавычках, следующий код не должен компилироваться, так как объект cat
уже уничтожен к тому моменту, когда процесс переходит к предложению catch
.Но это так, по крайней мере с 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;
}