Boost.Exception
Boost.Exception 库提供了一个新的异常类 boost::exception 允许给一个抛出的异常添加信息。 它被定义在文件 boost/exception/exception.hpp 中。 由于 Boost.Exception 中的类和函数分布在不同的头文件中, 下面的例子中将使用 boost/exception/all.hpp 以避免一个一个添加头文件。
cpp
#include <boost/exception/all.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/shared_array.hpp>
#include <exception>
#include <string>
#include <iostream>
// 可附加于异常中的信息。第一个参数叫做标签(tag),特定用来识别新建的数据类型。 通常是一个有特定名字的结构体。 第二个参数是与存储于异常中的tag相关的信息。
typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info;
typedef boost::error_info<struct tag_handle, std::string> errmsg_handle;
class allocation_failed : public boost::exception, public std::exception
{
public:
allocation_failed(std::size_t size)
: what_("allocation of " + boost::lexical_cast<std::string>(size) + " bytes failed")
{
}
virtual const char *what() const throw()
{
return what_.c_str();
}
private:
std::string what_;
};
boost::shared_array<char> allocate(std::size_t size)
{
if (size > 1000)
// Boost.Exception 提供了一个用以抛出异常的宏,它包含了函数名,以及文件名、行数的附加信息。
BOOST_THROW_EXCEPTION(allocation_failed(size));
return boost::shared_array<char>(new char[size]);
}
void save_configuration_data()
{
try
{
boost::shared_array<char> a = allocate(2000);
// saving configuration data ...
}
catch (boost::exception &e)
{
e << errmsg_info("saving configuration data failed");
throw;
}
}
void handle_eptr(std::exception_ptr eptr) // passing by value is ok
{
if (eptr == nullptr) return;
try
{
std::rethrow_exception(eptr); // 重新抛出
}
catch (allocation_failed &e) // 根据异常类型进行不同的处理
{
std::cerr << "Caught allocation_failed.\n"
<< boost::diagnostic_information(e);
}
catch (boost::exception &e)
{
std::cerr << "Caught boost::exception.\n"
<< boost::diagnostic_information(e);
}
catch (const std::logic_error &e)
{
std::cerr << "Caught logic_error \"" << e.what() << "\"\n";
}
catch (const std::exception &e)
{
std::cerr << "Caught exception \"" << e.what() << "\"\n";
}
}
int main()
{
std::exception_ptr eptr;
try
{
save_configuration_data();
}
catch (boost::exception &e)
{
e << errmsg_handle("Handle by handle_eptr");
eptr = std::current_exception(); // 获取异常指针
}
handle_eptr(eptr); // 统一异常处理
} 运行结果:
Caught allocation_failed.
/mnt/e/WorkSpace/test/boost_e.cpp(32): Throw in function boost::shared_array<char> allocate(std::size_t)
Dynamic exception type: boost::wrapexcept<allocation_failed>
std::exception::what: allocation of 2000 bytes failed
[tag_errmsg*] = saving configuration data failed
[tag_handle*] = Handle by handle_eptr