Error handling
E.13
Никогда не выбрасывайте исключение, являясь прямым владельцем объекта
Причина
Это была бы утечка.
Пример
void leak(int x) // don't: might leak
{
auto p = new int{7};
if (x < 0) throw Get_me_out_of_here{}; // might leak *p
// ...
delete p; // we might never get here
}
Один из способов избежать таких проблем - это последовательно использовать дескрипторы ресурсов:
void no_leak(int x)
{
auto p = make_unique<int>(7);
if (x < 0) throw Get_me_out_of_here{}; // will delete *p if necessary
// ...
// no need for delete p
}
Другое решение (часто лучше) было бы использовать локальную переменную, чтобы исключить явное использование указателей:
void no_leak_simplified(int x)
{
vector<int> v(7);
// ...
}
Примечание
Если у вас есть локальная "вещь", которая требует очистки, но не представлена объектом с деструктором, такая очистка должна также быть выполнена перед throw. Иногда, finally() может сделать такую несистематическую очистку немного более управляемой.