2015-03-10 25 views
6

ứng dụng lớn của tôi có cấu trúc này:Làm thế nào để bắt ngoại lệ có điều kiện?

int main() 
{ 
    try { 
     ... 
    } catch (std::exception& e) { 
     std::cout << "Fatal error: " << e.what() << (some more data) << std::endl; 
     return 1; 
    } 
} 

sâu bên trong các cuộc gọi stack, các đối tượng khác nhau kiểm tra trạng thái nội bộ của họ, ném std::runtime_exception nếu họ phát hiện một cái gì đó xấu. Trình xử lý ngoại lệ bao gồm tất cả bắt nó, in một số thông tin hữu ích vừa phải và chấm dứt chương trình.

Tuy nhiên, khi tôi đang gỡ lỗi trong MS Visual Studio, tôi có thể hưởng lợi từ việc không có bất kỳ trình xử lý ngoại lệ nào: Visual Studio có trình xử lý riêng, rất hữu ích, dừng ứng dụng của tôi tại vị trí ngoại lệ. Tôi có thể kiểm tra những gì đã đi sai.

Tôi làm cách nào để bắt các ngoại lệ của mình có điều kiện?

tôi thử như sau:

try { 
     ... 
    } catch (std::exception& e) { 
     if (IsDebuggerPresent()) 
      throw; 
     else 
      std::cout << "Fatal error: " << e.what() << (some more data) << std::endl; 
    } 

này đã đưa ra một kết quả kỳ lạ: Visual Studio bắt được ngoại lệ mà đã rethrown và chỉ cho tôi những dấu vết ngăn xếp tại điểm mà các ngoại lệ được ném. Tuy nhiên, tất cả các đối tượng trong ứng dụng của tôi dường như đã bị phá hủy và tôi không thể thấy ví dụ biến cục bộ hoặc thành viên.

tôi có thể làm cho các xử lý ngoại lệ có điều kiện trên một lá cờ biên soạn:

#ifdef NDEBUG 
    try { 
#endif 
     ... 
#ifdef NDEBUG 
    } catch (std::exception& e) { 
     std::cout << "Fatal error: " << e.what() << (some more data) << std::endl; 
    } 
#endif 

nhưng điều này là bất tiện vì tôi phải biên dịch lại tất cả mọi thứ nếu tôi muốn gỡ lỗi nó.

Vì vậy, làm cách nào để xử lý ngoại lệ có điều kiện (ví dụ: đối số dòng lệnh)?

+7

Hãy thử 'Debug' -> 'Exceptions' và đánh dấu vào "break trên ném" hộp cho ngoại lệ (s) bạn muốn bắt lấy. – CompuChip

+2

Một phương pháp tốt hơn sẽ được * có điều kiện * ném một ngoại lệ mà xử lý của bạn chỉ đơn giản là không thể bắt (thông qua một mức độ indirection), để nó lên đến trình gỡ lỗi để cướp 'em. –

+0

Nếu phương pháp của @ CompuChip phù hợp với bạn, nó chắc chắn là tốt hơn trong hai phương pháp này. – TonyK

Trả lời

0

Theo đề nghị của CompuChip, Visual Studio có thể phá vỡ thực hiện khi ném một ngoại lệ, không chỉ khi bắt một người vô hình!

Để kích hoạt tính này (trong Visual Studio 2012):

  1. Trong menu, đi Debug -> Exceptions
  2. Trong cửa sổ mở ra, đánh dấu vào ô "Ném" hộp cho trường hợp ngoại lệ tất cả C++ (đánh dấu chỉ std::exception là không đủ - tôi không biết tại sao)
  3. Chạy chương trình của bạn
0

Vì vậy, làm cách nào để xử lý ngoại lệ có điều kiện (tùy thuộc vào đối số dòng lệnh)?

Bằng cách viết mã cho nó: o]

Hãy xem xét mã gốc này:

int main() 
{ 
    try { 
     run_the_application(); // this part different than your example 
    } catch (std::exception& e) { 
     std::cout << "Fatal error: " << e.what() << (some more data) << std::endl; 
     return 1; 
    } 
} 

Code mới:

template<typename F> 
int fast_run(F functor) { functor(); return EXIT_SUCCESS; } 

template<typename F> 
int safe_run(F functor) 
{ 
    try { 
     functor(); 
    } catch (std::exception& e) { 
     std::cout << "Fatal error: " << e.what() << (some more data) << std::endl; 
     return EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
} 

template<typename F> 
int run(const std::vector<std::string>& args, F functor) 
{ 
    using namespace std; 
    if(end(args) != find(begin(args), end(args), "/d")) 
     return fast_run(functor); 
    else 
     return safe_run(functor); 
} 

int main(int argc, char** argv) 
{ 
    const std::vector<std::string> args{ argv, argv + argc }; 
    return run(args, run_the_application); 
} 
Các vấn đề liên quan