Если конструктор выбрасывает исключение, объект считается не созданным. Это означает, что деструктор вызываться не будет, но уже созданные части объекта могут потребовать очистки.
🚩Что происходит при исключении в конструкторе?
Когда исключение возникает в конструкторе:
Объект не создаётся – вызов конструктора считается неудачным.
Деструктор НЕ вызывается – потому что объект не был полностью создан.
Уже созданные члены класса должны быть очищены вручную (если используются RAII-объекты, они сами очистят ресурсы).
Исключение должно быть обработано – либо перехвачено (
try-catch), либо передано дальше. 🚩Пример исключения в конструкторе
#include <iostream>
#include <stdexcept>
class MyClass {
public:
MyClass() {
std::cout << "Конструктор\n";
throw std::runtime_error("Ошибка в конструкторе!");
}
~MyClass() {
std::cout << "Деструктор\n";
}
};
int main() {
try {
MyClass obj; // Попытка создать объект
} catch (const std::exception& e) {
std::cout << "Поймано исключение: " << e.what() << '\n';
}
}
Вывод программы
Конструктор
Поймано исключение: Ошибка в конструкторе!
🚩Как правильно работать с исключениями в конструкторе?
🟠Использовать RAII
Лучший способ избежать утечек – использовать RAII (объекты, которые сами освобождают ресурсы в деструкторе).
#include <iostream>
#include <memory>
#include <stdexcept>
class MyClass {
private:
std::unique_ptr<int> data; // Умный указатель RAII
public:
MyClass() : data(std::make_unique<int>(42)) {
throw std::runtime_error("Ошибка!");
}
};
int main() {
try {
MyClass obj;
} catch (const std::exception& e) {
std::cout << "Ошибка: " << e.what() << '\n';
}
}
🟠Использовать `try-catch` внутри конструктора
Если важно, чтобы объект всегда создавался, можно перехватывать исключение прямо в конструкторе.
class MyClass {
public:
MyClass() {
try {
throw std::runtime_error("Ошибка!");
} catch (...) {
std::cout << "Ошибка обработана, объект создан\n";
}
}
};🟠Использовать `noexcept(false)` или `noexcept(true)`
По умолчанию конструкторы могут выбрасывать исключения, но если мы точно знаем, что этого не произойдёт, лучше явно указать
noexcept: class SafeClass {
public:
SafeClass() noexcept {
std::cout << "Конструктор без исключений\n";
}
};Ставь 👍 и забирай 📚 Базу знаний