2016-09-11 19 views
5

xem xét mã này:ngoại lệ bắt cơ chế, C++

int main() 
{ 
    try 
    { 
     throw std::range_error(""); 
    } 
    catch (std::bad_alloc) 
    { 
     std::cout << "AAAA" << std::endl; 
     throw; 
    } 
    catch (std::range_error) 
    { 
     std::cout << "BBB" << std::endl; 
     throw; 
    } 
    catch (std::exception) 
    { 
     std::cout << "CCC" << std::endl; 
    } 
    std::cout << "DDD" << std::endl; 
} 

Ở đây tôi ném một ngoại lệ kiểu std::range_error và cố gắng nắm bắt nó.
Hợp lý khối catch đầu tiên không thể bắt được do loại không phù hợp (std::bad_allocstd::range_error).
Khối bắt thứ hai phải bắt được vì chúng là cùng loại std::range_error.
Và cũng có thể, khi tôi tính lại ngoại lệ trong khối đánh bắt thứ hai, nó phải bị bắt trong khối đánh bắt thứ ba.

Vì vậy, đầu ra của tôi phải

BBB 
CCC 
DDD 

Nhưng tôi chỉ nhận được những BBB đầu ra với việc chấm dứt.

Ai đó có thể giải thích cho tôi về hành vi không?

+2

ném thứ hai của bạn đã không xảy ra trong một 'khối try'. Vì vậy, nó không thể bị bắt. – Galik

+2

Nó không hoạt động theo cách đó.Mỗi khối try-catch chỉ nhận được một phát ở ngoại lệ cho dù có bao nhiêu mệnh đề bắt được. Các ngoại lệ được ném bởi bất kỳ điều khoản bắt nào đều không bị bắt trong khối try-catch đó. – davidbak

+0

điều đó có nghĩa là ngay cả khi tôi có nhiều khối catch của loại ngoại lệ, chỉ cái đầu tiên mới bắt được ngoại lệ, tôi có đúng không? –

Trả lời

6

Khi bạn tái throw một ngoại lệ, bạn đang ném nó hoàn toàn ra khỏi bối cảnh của khối xử lý ngoại lệ hiện tại .... Vì vậy,

try 
{ 
    throw std::range_error(""); 
} 
catch (std::bad_alloc) 
{ 
    std::cout << "AAAA" << std::endl; 
    throw; 
} 
catch (std::range_error) 
{ 
    std::cout << "BBB" << std::endl; 
    throw; 
} 
catch (std::exception) 
{ 
    std::cout << "CCC" << std::endl; 
} 

một xử lý ngoại lệ khối. Do đó, khi gặp phải throw đầu tiên trong bất kỳ khối nào trong số catch, nó sẽ chặn toàn bộ khối để tìm một khối xử lý khác (try-catch) bên ngoài phạm vi hiện tại. nếu không tìm thấy, chương trình chấm dứt.

Xin xem try-catch block in C++

Để in như ban đầu bạn nghĩ ... Live On Coliru ...

int main() 
{ 
    try{ 
     try{ 
      try{ 
       throw std::range_error(""); 
      } 
      catch (std::bad_alloc) { 
       std::cout << "AAAA" << std::endl; 
       throw; 
      } 
     } 
     catch (std::range_error) { 
      std::cout << "BBB" << std::endl; 
      throw; 
     } 
    } 
    catch (std::exception){ 
     std::cout << "CCC" << std::endl; 
    } 
    std::cout << "DDD" << std::endl; 
} 

Prints:

BBB 
CCC 
DDD 

Đối với hồ sơ: xin vui lòng tránh sử dụng các ngoại lệ cho kiểm soát dòng chảy có thể được thực hiện bằng thang đơn giản if-else trong mã sản xuất

4

này throw:

catch (std::range_error) 
{ 
    std::cout << "BBB" << std::endl; 
    throw; // <== this one 
} 

không phải là bản thân trong cơ thể của một try, vì vậy khi cơ chế xử lý ngoại lệ sẽ tiếp tục đi ra một phạm vi tại một thời điểm cho đến khi nó tìm thấy một. Vì không có bên ngoài khác try, ngoại lệ không bị bắt.

Không có sự hối cải trong xử lý ngoại lệ.

5

Để bắt lại dải_khoảng và cần có khối bắt thử bên ngoài mới.

#include <iostream> 

int main() 
{ 
    //outer try catch ------------------------ 
    try { 

    // inner try catch --------------------- 
    try 
    { 
     throw std::range_error(""); 
    } 
    catch (std::bad_alloc) 
    { 
     std::cout << "AAAA" << std::endl; 
     throw; 
    } 
    catch (std::range_error) 
    { 
     std::cout << "BBB" << std::endl; 
     throw; 
    } 
    // ------------------------------- 
    } 

    catch (std::exception) 
    { 
    std::cout << "CCC" << std::endl; 
    } 
    // -------------------------------- 

    std::cout << "DDD" << std::endl; 
} 

Output

BBB 
CCC 
DDD 
Các vấn đề liên quan