Назад к вопросам
Middle+
106
questionbank
О чем следует помнить при выбрасывании исключений в конструкторе?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
При выбрасывании исключения в конструкторе следует помнить:
- Частично построенный объект: Если исключение выбрасывается до завершения инициализации всех членов класса, объект считается частично построенным. Его деструктор не будет вызван.
- Освобождение ресурсов: Ресурсы, захваченные до момента выбрасывания исключения (например, выделенная память в конструкторах инициализированных на данный момент членов), должны быть явно освобождены. Идиома RAII (Resource Acquisition Is Initialization) является идеальным решением для автоматического управления ресурсами в таких случаях.
- Отсутствие деструктора: Так как деструктор не вызывается, код, который полагается на деструктор для очистки (например, освобождение памяти, закрытие файлов), не выполнится.
- Утечки ресурсов: Без должной заботы об освобождении ресурсов при выбрасывании исключения в конструкторе могут произойти утечки памяти, файловых дескрипторов и других ресурсов.
Пример использования RAII для предотвращения утечек:
#include <iostream>
#include <memory> // для std::unique_ptr
class Resource {
public:
Resource() { std::cout << "Resource acquired\n"; }
~Resource() { std::cout << "Resource released\n"; }
};
class MyClass {
private:
std::unique_ptr<Resource> res; // Используем RAII (unique_ptr)
public:
MyClass() : res(std::make_unique<Resource>()) {
std::cout << "MyClass constructor starts\n";
// Предположим, здесь происходит что-то, что может вызвать исключение
if (true) { // Имитация условия для выбрасывания исключения
throw std::runtime_error("Error during construction");
}
std::cout << "MyClass constructor finishes\n";
}
~MyClass() {
std::cout << "MyClass destructor\n";
}
};
int main() {
try {
MyClass obj;
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
}
return 0;
}
В данном примере std::unique_ptr владеет ресурсом Resource. Если исключение выбрасывается в конструкторе MyClass после инициализации res, деструктор std::unique_ptr будет вызван автоматически, гарантируя освобождение ресурса Resource.