2010-02-18 42 views
9

Đây là thiết lập.Điều gì sẽ xảy ra nếu tôi sử dụng "ném"; mà không có ngoại lệ để ném?

Tôi có chương trình C++ gọi một số chức năng, tất cả đều có khả năng ném cùng một ngoại lệ và tôi muốn cùng một hành vi cho các ngoại lệ trong mỗi hàm (ví dụ: thông báo lỗi in & đặt lại tất cả dữ liệu về mặc định cho exceptionA; chỉ cần in cho exceptionB; shut-down cleanly cho tất cả các ngoại lệ khác).

Nó có vẻ như tôi sẽ có thể thiết lập các hành vi đánh bắt để gọi một chức năng riêng mà chỉ đơn giản rethrows lỗi, và thực hiện các quảng cáo, như vậy:

void aFunction() 
{ 
    try{ /* do some stuff that might throw */ } 
    catch(...){handle();} 
} 

void bFunction() 
{ 
    try{ /* do some stuff that might throw */ } 
    catch(...){handle();} 
} 

void handle() 
{ 
    try{throw;} 
    catch(anException) 
    { 
     // common code for both aFunction and bFunction 
     // involving the exception they threw 
    } 
    catch(anotherException) 
    { 
     // common code for both aFunction and bFunction 
     // involving the exception they threw 
    } 
    catch(...) 
    { 
     // common code for both aFunction and bFunction 
     // involving the exception they threw 
    } 
} 

Bây giờ, những gì sẽ xảy ra nếu "xử lý" được gọi bên ngoài lớp ngoại lệ. Tôi biết rằng điều này sẽ không bao giờ xảy ra, nhưng tôi tự hỏi nếu hành vi này không được xác định bằng tiêu chuẩn C++.

+0

Nó bị chấm dứt, nhưng bạn muốn tôi làm gì ?, cung cấp cho bạn trình biên dịch để thực thi chương trình này để bạn có thể xác minh kết quả. –

+0

Tất cả trình biên dịch sẽ làm là biên dịch nó. Và nó sẽ biên dịch, bởi vì không có gì về định nghĩa * của xử lý để cảnh báo người dùng rằng nó chắc chắn sẽ yêu cầu một ngoại lệ được tải. Trình biên dịch không thể cho bạn biết nhiều hữu ích về hành vi không xác định, đặc biệt là một cái gì đó như thế này sẽ không được chọn cho đến thời gian chạy. – deworde

Trả lời

16

Nếu handle() được gọi bên ngoài ngữ cảnh ngoại lệ, bạn sẽ throw mà không xử lý ngoại lệ. Trong trường hợp này, tiêu chuẩn (xem phần 15.5.1) quy định rằng

Nếu không có ngoại lệ nào hiện đang được xử lý, thực hiện terminate().

để ứng dụng của bạn sẽ chấm dứt. Đó có lẽ không phải là những gì bạn muốn ở đây.

+0

Vâng, không có lý do lành mạnh nào để gọi "handle()" nếu bạn không ở trong một khối catch, nhưng tôi đã quan tâm đến việc những gì đã xảy ra sẽ được xác định. Đó là một câu trả lời hoàn hảo. Cảm ơn! – deworde

5

Nếu bạn sử dụng ném bên trong khối catch, nó sẽ trả lại ngoại lệ. Nếu bạn sử dụng ném bên ngoài của một khối catch, nó sẽ chấm dứt ứng dụng.

+0

Câu trả lời hay, mặc dù John rõ ràng hơn. Cảm ơn! – deworde

1

Không bao giờ, không bao giờ, không bao giờ sử dụng bắt (...) vì bạn có thể gặp lỗi ứng dụng mà bạn không muốn bắt, ví dụ: lỗi, vi phạm truy cập (tùy thuộc vào cách bạn biên soạn).

Đọc cuốn sách tuyệt vời của John Robbins (Gỡ lỗi các ứng dụng Windows) trong đó ông giải thích chi tiết hơn tại sao bạn không nên làm điều đó.

+0

http://stackoverflow.com/questions/2183113/using-catch-ellipsis-for-post-mortem-analysis –

+2

Điều này hoàn toàn không liên quan đến câu hỏi của tôi. Ngoài ra, nó không chính xác, như SF được hiển thị ở trên. Có rất nhiều lý do hoàn hảo để sử dụng (...), miễn là bạn xử lý nó một cách chính xác. Ví dụ: Giả sử tôi muốn phát hành khóa trên nội dung được chia sẻ. Tôi có thể chờ cho đến khi nó đạt đến một destructor, nhưng tốt hơn để làm điều đó ngay sau khi tôi chắc chắn tôi không còn cần nó. Sau đó tôi có thể truy cập lại từ bên trong khối catch (...) {} nếu tôi muốn đảm bảo rằng các vi phạm và lỗi truy cập vẫn dẫn đến chấm dứt. – deworde

Các vấn đề liên quan