Một cách hay trong C++ để phát hiện trong một destructor là nó đang được chạy trong khi thư giãn của ngăn xếp do một ngoại lệ được ném như trái ngược với một lối ra bình thường của phạm vi kích hoạt các destructor? Tôi muốn biết để tôi có thể tạo một lớp có một số mã dọn dẹp luôn luôn chạy trên lối ra bình thường nhưng bỏ qua khi một ngoại lệ xảy ra.Phát hiện khi destructor chạy do ngoại lệ bị ném?
Trả lời
std::uncaught_exception()
(quy định tại <exception>
) sẽ cho bạn biết trong destructor của bạn nếu nó được gọi vì một ngoại lệ:
class A
{
public:
~A()
{
if (std::uncaught_exception()) {
// Called because of an exception
} else {
// No exception
}
}
};
Tốt, tôi chưa bao giờ biết điều này đã tồn tại! :-) –
Không đẹp như bạn nghĩ - hãy xem bài viết được liên kết trên bài đăng của tôi. – Simon
Dưới đây là một cách tôi có thể nghĩ ra, nhưng có vẻ như vụng về:
{
myCleanupClass unwindAction;
try {
// do some work which may throw exception.
} catch (...) {
unwindAction.disableDestructorWork();
throw;
}
}
Đừng làm điều đó trừ khi bạn có lý do chính đáng. Ngăn xếp thư giãn là một tính năng ngôn ngữ mà tất cả các đối tượng tự động bên trong khối try
sẽ được thực thi để deallocate, để các nguồn lực bên trong chúng có cơ hội để phát hành.
Bạn muốn bỏ qua dọn dẹp trong dtor trong khi thư giãn thư giãn, bỏ qua mục đích ban đầu của nó. Và bạn sẽ có nguy cơ bị rò rỉ tài nguyên.
Ví dụ
class CDBConnection
{
public:
CDBConnection()
{
m_db.open();
}
~CDBConnection()
{
if (!std::uncaught_exception())
m_db.close();
// if this is called during a stack unwinding,
// your DB connection will not be closed for sure.
// That's a resource leakage.
}
//..
private:
DB m_db;
};
void main()
{
//..
try
{
// code that may throw
CDBConnection db;
//..
}
catch(const CDBException& exp)
{
// properly handle the exception
}
}
lẽ this bài viết sẽ giúp bạn. Bài viết sẽ cho bạn thấy các vấn đề với std :: uncaught_exception() và chứa một lời khuyên làm thế nào để đối phó với các ngoại lệ trong các destructors.
- 1. Destructor không được gọi khi một ngoại lệ được ném
- 2. Gửi email khi ngoại lệ bị ném
- 3. Ngoại lệ trong destructor
- 4. Ngoại lệ được ném khi WndProc bị quá tải
- 5. Tại sao ngoại lệ .net không bị phát hiện?
- 6. Trả lại sau khi ném ngoại lệ
- 7. BeginInvoke ném ngoại lệ
- 8. Ngoại lệ khi chạy System.Threading.Tasks.Task
- 9. ném mới std :: ngoại lệ vs ném std :: ngoại lệ
- 10. Trạng thái con trỏ đối tượng Sau khi phát hiện ra constructor ném ngoại lệ - C++
- 11. recursive_directory_iterator ném ngoại lệ
- 12. Các trường hợp ngoại lệ được phát hiện sau khi đã bị bắt
- 13. Khi trả lại bool, hãy ném ngoại lệ và ngoại lệ nào để ném
- 14. autoFocus ném ngoại lệ
- 15. Android Visualizer lớp ném ngoại lệ thời gian chạy
- 16. TransactionScope ném ngoại lệ
- 17. C# Ngoại lệ ném lại
- 18. Ngoại lệ ném
- 19. ném ngoại lệ
- 20. WebAuthenticationBroker.AuthenticateAsync ném ngoại lệ
- 21. LLVM ngoại lệ ném
- 22. C# finalizer ném ngoại lệ?
- 23. Ném và bắt ngoại lệ
- 24. Destructor gọi một chức năng có thể ném ngoại lệ trong C++
- 25. C# trình biên dịch lỗ hổng ?: Không phát hiện các phương pháp luôn ném ngoại lệ
- 26. Có một lý do hợp lệ nào để bỏ qua một ngoại lệ bị bắt
- 27. Những gì destructors được chạy khi constructor ném một ngoại lệ?
- 28. Ném ngoại lệ trong bộ xử lý ngoại lệ
- 29. Làm cho Struts gửi 500 lỗi máy chủ nội bộ khi ngoại lệ bị ném
- 30. Ngoại lệ được ném và không bị phát hiện trong IE7 (jquery.signalR-0.5.1.js, dòng 22 ký tự 9)
Câu hỏi thú vị! Tôi bị cám dỗ để nói rằng nó không thể được thực hiện, bởi vì các đối tượng không thực sự biết rằng một ngoại lệ là hoạt động, họ chỉ đi ra khỏi phạm vi như là ngoại lệ thư giãn ngăn xếp, giống như nếu họ đi ra khỏi bất kỳ khác phạm vi. Nếu bất cứ điều gì bạn cần một số "hack" nền tảng cụ thể ... –
Tò mò lý do tại sao bạn muốn tránh dọn dẹp trong khi mở thư? –
@Eric Z: Tôi đã nghĩ đến việc sử dụng tính năng này để ghi nhật ký 'stack' tự động. Một cái gì đó dọc theo dòng của 'Đăng nhập xxx ("funcA -", arg1, arg2, arg3); ', nhưng dụng cụ chức năng là tẻ nhạt. –