system
C++中处理错误的最佳方式是使用异常,但操作系统和许多底层AP工不具有这个能力,它们一般使用更通用也更难以操作的错误代码来表示出错的原因,不同的操作系统的错误代码通常不是兼容的,这给编写跨平台的程序带来了很大的麻烦。
system库使用轻量级的对象封装了操作系统底层的错误代码和错误信息,使调用操作系统功能的程序可以被很容易地移植到其他操作系统。它作为基础部件被chronovfilesystem和 asio等库调用,并且被接受为c++标准(C++11.19.5)。
jamfile 指定 lib
lib boost_system;
system 库位于名字空间boost : :system,需要包含头文件<boost/system/error_code.hpp>(注意与C++标准的名字<system_error>不同),即:
#define BOOST_ERROR_CODE_HEADER_ONLY //无需编译即可使用system库
#include <boost/system/error_code. hpp>
using namespace boost: :system;
错误值
system库在名字空间boost : :system: :errc下定义了一个很大的枚举类errc_t它定义了通用的可移植的错误代码,我们应当尽量使用它来标记错误原因:
namespace errc
{
enum errc{
success=0,
address_family_not_supported,
address_in_use,
address_not_available,
already_connected,
...
}
}
system库还在头文件<boost/system/linux_error.hpp>和<boost/system/windows_error.hpp>里分别定义了Linux和windows操作系统特定的错误值枚举,分别位于名字空间boost::system : : linux_error和 boost ::system : : windows_error。如果针对这两个操作系统做特定编程,则可以包含这两个头文件。
错误类别
system库的核心类是error_category、error_code和error_condition。
error category
是一个抽象基类,用于标识错误代码的类别,它的类摘要如下:
class error_category:public noncopyable
{
public:
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT=0;
virtual string message(error_code::value_type ev)const =0;
virtual error_condition default_error_condition(int ev)const;
virtual bool equiavlent(int code,const error_condition&condition);
virtual bool equiavlent(const error_code&code,int condition);
}
成员函数name( )可以获得类别的名称;
message()可以获得错误代码ev对应的描述信息;
default_error_condition ()是一个工厂方法,它由错误代码 ev产生一个error_condition对象;
equivalent()用于比较两个错误代码是否相等。
error_category 不能直接使用,必须使用继承的方式生成它的子类。system库在匿名名字空间里预定义了两个子类system_error_category和generic_error_category,用于表示系统错误和通用的可移植错误,可以用位于名字空间boost ::system的自由函数system_category()和 generic_category ()间接访问。
class my_category:public error_category
{
public:
virtual const char* name()const BOOST_SYSTEM_NOEXCEPT
{return "myapp_category";}
virtual std::string message(int ev)const{
std::string msg;
switch (ev)
{
case 0:
msg="ok"/* constant-expression */:
/* code */
break;
default:
msg="some error";
break;
}
return msg;
}
};
错误代码
error_code和 error_condition都用于表示错误代码,但error_code更接近操作系统和底层API,而error_condition则更偏重于可移植。两者的声明很类似,但
error_code 多了一个 default_error_condition ()的方法,可以把 error_code 转换成error_condition。
class error_code
{
public:
error_code();
error_code(int val,const error_category&cat);
void assign(int val,const error_category& cat);
void clear();
int value() const;
const error_category&category()const;
error_condition default_error_condition()const;
std::string message()const;
...
};
error_code和 error_condition都可以从一个整数错误值或者errc_t枚举构造,并同时指定所属的错误类别。如果无参构造,那么错误值将会是0(无错误)。
error_code对象内部的值可以用value ()获得,获得错误描述要使用message ( ) ,它将调用error_category的message ()返回描述信息。函数category ()可以返回错误代码所属的类别,因此message ()相当于:
ec.category().message(ec.value)
不同的错误类别决定了error_code 的含义,相同的错误代码如果属于不同的类别,那么将具有不同的含义。
void error_category1()
{
my_category my_cat;
error_code ec(10,my_cat);
std::cout<<ec.value()<<ec.message()<<std::endl;
ec=error_code(10,system_category());
std::cout<<ec.value()<<ec.message()<<std::endl;
}
//
10 some error
10 No child processes
错误异常
system库还提供一个异常类system_error,它是 std: :runtime_error的子类,是对error_code的一个适配,可以把error_code应用到C++的异常处理机制之中。
system_error位于名字空间boost : : system,使用时需要另外包含头文件<boost/system/ system_error.hpp>,即;
#include <boost/ system/ system_error.hpp>
using namespace boost: :system;
示范用法:
try{
throw system_error(
error_code(5,system_category()));
}
catch(system_error&e)
{
cout<<e.what()
}