#новичкам
Теперь мы разобрались с основным кейсом. Давайте подробнее рассмотрим, что будет, если мы будет работать с явно бросающими деструктором.
Единственный важный вопрос, который здесь можно задать: а что будет, если деструктор вызовется при раскрутке стека?
Вот так:
struct Class {
// HERE
~Class() noexcept(false) {throw 1;}
};
int main() {
try {
Class cl;
throw 1.0;
} catch(...) {
std::cout << "caught exception" << std::endl;
}
}В этом случае при бросании 1.0, исключение увидит блок catch и перед входом в него начнет раскручивать стек, вызывая деструкторы всех локальных объектов во всех фреймах, которые пролетело исключение.
В нашем коде деструктор Class будет вызван до блока catch и получается, что у нас ситуация, в которой есть 2 необработанных исключения. Эта ситуация называется double exception и она приводит к немедленному вызову std::terminate.
Именно поэтому вы не должны бросать исключения в деструкторах. Именно поэтому все деструкторы по умолчанию noexcept. Потому что невозможно безопасно работать с классом, у которого бросающий деструктор, в мире, где другие сущности тоже могут сгенерировать исключения.
Теперь вы профессионально будете отвечать всем интервьюерам, заслужите много уважения и конфеты(но это не точно).
Stay safe. Stay cool.
#cppcore #cpp11 #interview