Trong đoạn mã sau, biến dựa trên ngăn xếp 'ex' được ném và bị bắt trong một hàm vượt quá phạm vi mà từ đó đã được khai báo. Điều này có vẻ hơi lạ đối với tôi, vì các biến dựa trên stack (AFAIK) không thể được sử dụng bên ngoài phạm vi mà chúng đã được khai báo (ngăn xếp được bỏ trống).Ngoại lệ được phân bổ như thế nào trên ngăn xếp vượt quá phạm vi của họ?
void f() {
SomeKindOfException ex(...);
throw ex;
}
void g() {
try {
f();
} catch (SomeKindOfException& ex) {
//Handling code...
}
}
Tôi đã thêm một tuyên bố in để destructor SomeKindOfException và nó cho thấy rằng cựu được destructed khi nó đi ra khỏi phạm vi trong f() nhưng sau đó nó bị bắt trong g() và destructed một lần nữa một khi nó đi ra khỏi phạm vi đó là tốt.
Bất kỳ trợ giúp nào?
Có đúng không khi sử dụng tham chiếu tại đây? 'catch (SomeKindOfException & ex)' Tôi nghĩ điều này là nguy hiểm, vì nó không gọi hàm tạo bản sao và bạn truy cập vào vùng bộ nhớ thuộc về chồng f() thỏa thuận! Tôi đoán rằng điều này phải chính xác thay vào đó: 'bắt (SomeKindOfException ex)' – Dacav
Đúng (và thậm chí tốt hơn - xem http://www.parashift.com/c++-faq-lite/exceptions.html phần 17.7) để bắt bằng tham chiếu. Khi câu trả lời cho trạng thái câu hỏi của tôi, ngoại lệ bị bắt không phải là đối tượng dựa trên chồng được ném, mà là một bản sao của nó nằm ở một nơi khác có thể tồn tại ngăn xếp thư giãn, do đó không có rủi ro như vậy. –
Vâng, tôi chạy một số thử nghiệm tối hôm qua và có, Đó là cách tốt hơn sử dụng các tài liệu tham khảo. Xem tại đây: http: // pastebin.com/8YQuNAux Nếu bạn thực hiện nó, bạn có thể nhận thấy rằng ngoại lệ được phân bổ động (theo nghĩa 'mới') ở mọi điểm bắt mà không cần tham khảo: Nếu bạn sử dụng tham chiếu, thay vào đó, nó chỉ được phân bổ một lần và tự động bị hủy khi phạm vi bị chấm dứt. Ngoài ra tôi nghĩ hành vi này phụ thuộc hoàn toàn vào trình biên dịch. – Dacav