<c++>在异常处理中,您需要知道什么异常以及异常将在哪里发生吗?你能编写一段代码,打印并通知我们程序中某个地方发生了异常吗?我的意思是我有一个程序,我不知道是否会发生异常,如果发生异常,它会打印出来通知我们。
异常处理是您应该设计的,事实上它与RAII (https://en.cppreference.com/w/cpp/language/raii)一起工作得非常好。(不是在嵌入式平台上使用异常,不是很流行,因为一些运行时开销)。我个人喜欢异常的一点是,它将错误处理从正常的程序流程中分离出来(如果处理得当,几乎不会有任何if then else检查)
// Exception handling should be part of your overal design.And many standard library functions can throw exceptions, It is always up to you where you handle them.
#include <iostream>
#include <string>
#include <stdexcept>
int get_int_with_local_exception_handling()
{
do
{
try
{
std::cout << "Input an integer (local exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
// stoi is a function that can throw exceptions
// look at the documentation https://en.cppreference.com/w/cpp/string/basic_string/stol
// and look for exceptions.
//
int value = std::stoi(input);
// if input was ok, no exception was thrown so we can return the value to the client.
return value;
}
// catch by const reference, it avoids copies of the exception
// and makes sure you cannot change the content
catch (const std::invalid_argument& e)
{
// std::exceptions always have a what function with readable info
std::cout << "handling std::invalid_argument, " << e.what() << "n";
}
catch (const std::out_of_range& e)
{
std::cout << "handling std::out_of_range, " << e.what() << "n";
}
} while (true);
}
int get_int_no_exception_handling()
{
std::cout << "Input an integer (without exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
int value = std::stoi(input);
return value;
}
int main()
{
try
{
// this function shows you can handle exceptions locally
// to keep program running
auto value1 = get_int_with_local_exception_handling();
std::cout << "your for input was : " << value1 << "n";
// this function shows that exceptions can be thrown without
// catching, but then the end up on the next exception handler
// on the stack, which in this case is the one in main
auto value2 = get_int_no_exception_handling();
std::cout << "your input was : " << value1 << "n";
return 0;
}
catch (const std::exception& e)
{
std::cout << "Unhandled exception caught, program terminating : " << e.what() << "n";
return -1;
}
catch (...)
{
std::cout << "Unknown, and unhandled exception caught, program terminatingn";
}
}
是和不是。
不,因为通过throw some_exception;
抛出的任何异常都可以通过catch(...)
捕获。
是的,因为catch(...)
不是很有用。你只知道有一个例外,而不是更多。
异常通常携带有关您希望在catch中使用的原因的信息。只有作为最后的手段,或者当您需要绝对确保不会错过任何异常时,才应该使用catch(...)
:
try {
might_throw_unknown_exceptions();
} catch(std::exception& err) {
std::cout << "there was a runtime error: " << err.what();
} catch(...) {
std::cout << "an unknown excpetion was thrown.";
}
c++标准库很少使用继承。异常是唯一被广泛使用的地方:所有标准异常都继承自std::exception
,并且从它继承自定义异常也是一种良好的实践。