【BOOST C++ 17 出错处理】(2)Boost.System
创始人
2024-02-15 14:10:07

一、说明

以下库支持错误处理。

  • Boost.System 提供类来描述和识别错误。自 C++11 以来,这些类已成为标准库的一部分。
  • Boost.Exception 使得在抛出异常后附加数据成为可能。

二、关于 Boost.System库

Boost.System

        Boost.System 是一个库,本质上定义了四个类来识别错误。所有四个类都已添加到 C++11 的标准库中。如果您的开发环境支持 C++11,则无需使用 Boost.System。然而,由于许多 Boost 库使用 Boost.System,您可能会通过其他库遇到 Boost.System。

        boost::system::error_code 是 Boost.System 中最基本的类;它表示特定于操作系统的错误。因为操作系统通常会枚举错误,所以 boost::system::error_code 将错误代码保存在一个 int 类型的变量中。示例 55.1 说明了如何使用此类。

        示例 55.1。使用 boost::system::error_code

#include 
#include using namespace boost::system;void fail(error_code &ec)
{ec = errc::make_error_code(errc::not_supported);
}int main()
{error_code ec;fail(ec);std::cout << ec.value() << '\n';
}

Example 55.1 

        示例 55.1 定义了用于返回错误的函数 fail()。为了让调用者检测 fail() 是否失败,boost::system::error_code 类型的对象通过引用传递。 Boost 库提供的许​​多函数都像这样使用 boost::system::error_code。例如,Boost.Asio 提供函数 boost::asio::ip::host_name(),您可以将类型为 boost::system::error_code 的对象传递给该函数。

        Boost.System 在命名空间 boost::system::errc 中定义了许多错误代码。示例 55.1 将错误代码 boost::system::errc::not_supported 分配给 ec。因为 boost::system::errc::not_supported 是一个数字,而 ec 是 boost::system::error_code 类型的对象,所以函数 boost::system::errc::make_error_code() 被调用。此函数使用相应的错误代码创建一个类型为 boost::system::error_code 的对象。

        在 main() 中,value() 在 ec 上被调用。此成员函数返回存储在对象中的错误代码。

        默认情况下,0 表示没有错误。每隔一个数字表示一个错误。错误代码值取决于操作系统。有关错误代码的说明,请参阅操作系统的文档。

        除了 value() 之外,boost::system::error_code 还提供了成员函数 category(),它返回一个 boost::system::error_category 类型的对象。

        错误代码只是数值。虽然 Microsoft 等操作系统制造商能够保证系统错误代码的唯一性,但应用程序开发人员几乎不可能在所有现有应用程序中保持错误代码的唯一性。这将需要一个中央数据库,其中包含来自世界各地所有软件开发人员的错误代码,以避免为不同的错误重复使用相同的代码。因为这是不切实际的,所以存在错误类别。

        boost::system::error_code 类型的错误代码属于可以使用成员函数 category() 检索的类别。使用 boost::system::errc::make_error_code() 创建的错误自动属于通用类别。如果错误未明确分配给另一个类别,则这是错误所属的类别。

        示例 55.2。使用 boost::system::error_category

#include 
#include using namespace boost::system;void fail(error_code &ec)
{ec = errc::make_error_code(errc::not_supported);
}int main()
{error_code ec;fail(ec);std::cout << ec.value() << '\n';std::cout << ec.category().name() << '\n';
}

        如示例 55.2 所示,category() 返回错误的类别。这是一个类型为 boost::system::error_category 的对象。只有几个成员函数。例如,name() 检索类别的名称。示例 55.2 将泛型写入标准输出。

        您还可以使用独立函数 boost::system::generic_category() 来访问通用类别。

        Boost.System 提供了第二类。如果您调用独立函数 boost::system::system_category(),您将获得对系统类别的引用。如果您将类别的名称写入标准输出,则会显示系统。

        错误由错误代码和错误类别唯一标识。因为错误代码只需要在一个类别中是唯一的,所以只要您想要定义特定于您的程序的错误代码,就应该创建一个新类别。这使得使用不干扰其他开发人员的错误代码的错误代码成为可能。

        示例 55.3。创建错误类别

#include 
#include 
#include class application_category :public boost::system::error_category
{
public:const char *name() const noexcept { return "my app"; }std::string message(int ev) const { return "error message"; }
};application_category cat;int main()
{boost::system::error_code ec{129, cat};std::cout << ec.value() << '\n';std::cout << ec.category().name() << '\n';
}

        通过创建从 boost::system::error_category 派生的类来定义新的错误类别。这需要您定义各种成员函数。至少必须提供成员函数 name() 和 message(),因为它们在 boost::system::error_category 中被定义为纯虚拟成员函数。对于其他成员函数,如果需要,可以覆盖默认行为。

        name() 返回错误类别的名称,而 message() 用于检索特定错误代码的错误描述。与示例 55.3 不同,通常评估参数 ev 以返回基于错误代码的描述。

        新创建的错误类别类型的对象可用于初始化错误代码。示例 55.3 使用新类别 application_category 定义错误代码 ec。因此,错误代码 129 不再是一般错误;相反,它的含义由新错误类别的开发人员定义。

注意

        要使用 Visual C++ 2013 编译示例 55.3,请删除关键字 noexcept。此版本的 Microsoft 编译器不支持 noexcept。

        boost::system::error_code 提供了一个名为 default_error_condition() 的成员函数,它返回一个类型为 boost::system::error_condition 的对象。 boost::system::error_condition 的接口几乎与 boost::system::error_code 的接口相同。唯一的区别是成员函数 default_error_condition(),它仅由 boost::system::error_code 提供。

        示例 55.4。使用 boost::system::error_condition

#include 
#include using namespace boost::system;void fail(error_code &ec)
{ec = errc::make_error_code(errc::not_supported);
}int main()
{error_code ec;fail(ec);boost::system::error_condition ecnd = ec.default_error_condition();std::cout << ecnd.value() << '\n';std::cout << ecnd.category().name() << '\n';
}

        boost::system::error_condition 就像 boost::system::error_code 一样使用。这就是为什么可以为类型为 boost::system::error_condition 的对象调用成员函数 value() 和 category() 的原因,如示例 55.4 所示。

        类 boost::system::error_code 用于与平台相关的错误代码,而 boost::system::error_condition 用于访问与平台无关的错误代码。成员函数 default_error_condition() 将依赖于平台的错误代码转换为类型为 boost::system::error_condition 的平台无关错误代码。

        您可以使用 boost::system::error_condition 来识别与平台无关的错误。例如,此类错误可能是对不存在文件的访问失败。虽然操作系统可能提供不同的接口来访问文件并可能返回不同的错误代码,但尝试访问不存在的文件在所有操作系统上都是错误的。从操作系统特定接口返回的错误代码存储在 boost::system::error_code 中。描述访问不存在文件失败的错误代码存储在 boost::system::error_condition 中。

        Boost.System 提供的最后一个类是 boost::system::system_error,它派生自 std::runtime_error。它可用于在异常中传输类型为 boost::system::error_code 的错误代码。

        示例 55.5。使用 boost::system::system_error

#include 
#include 
#include using namespace boost::system;void fail()
{throw system_error{errc::make_error_code(errc::not_supported)};
}int main()
{try{fail();}catch (system_error &e){error_code ec = e.code();std::cerr << ec.value() << '\n';std::cerr << ec.category().name() << '\n';}
}

        在示例 55.5 中,独立函数 fail() 已更改为在出现错误时抛出类型为 boost::system::system_error 的异常。此异常可以传输类型为 boost::system::error_code 的错误代码。异常在 main() 中捕获,它将错误代码和错误类别写入标准错误。函数 boost::asio::ip::host_name() 的第二个变体就像这样工作。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...