Я думаю, это поможет вам следить за тем, что происходит, если вы добавите конструктор и скопируете конструктор в свой код.
#include <iostream>
#include <string>
class Box {
public:
std::string show() {
std::cout << "Box show executed - " << this << std::endl;
return "msg";
};
Box() {
std::cout << "Box constructor is executed " << this << std::endl;
}
Box(const Box& rhs) {
std::cout << "Box copy constructor is executed " << this << std::endl;
}
~Box() {
std::cout << "Box destructor is executed " << this << std::endl;
};
};
int main() {
try {
Box obj;
std::cout << "Coming here" << std::endl;
throw obj;
}
catch (Box msg) {
std::cout << "I have caught the exception: \n" << msg.show() << std::endl;
}
}
Это дает следующий вывод:
/*
Box constructor is executed 0051FB0B
Coming here
Box copy constructor is executed 0051FA33
Box copy constructor is executed 0051FAFF
Box destructor is executed 0051FB0B
Box show executed - 0051FAFF
I have caught the exception: msg
Box destructor is executed 0051FAFF
Box destructor is executed 0051FA33
*/
Таким образом, вы можете видеть ответ на # 1 в том, что два новых объекта создаются во время броска и улова. Сразу после этого исходный объект разрушается, поскольку теперь он находится вне области видимости блока.
Следующая часть немного сбивает с толку, потому что есть два вложенных оператора std :: cout. В этом случае компилятор решил полностью разрешить выражение msg.show () до того, как произвел вывод для первой части строки «Я поймал исключение ...». Таким образом, поскольку он разрешал значение для msg.show (), msg.show () сначала выдало свою собственную строку вывода «Box show .....», поэтому она появилась первой. Как С.М. В его ответе указывается, что порядок, в котором компилятор выбирает оценку вложенного std :: cout, определяется реализацией, и этот порядок операций не гарантируется.
Наконец, объект, созданный в catch, уничтожается, а затем объект, созданный в результате попытки, уничтожается.