Boost应用实践
Boost.Log
在使用 Boost.Log 时,需要清楚知道它对日志功能实现的几个定义:
-
日志记录(Log record):我们使用 Boost.Log 每打印一行 log 都将产生一个日志记录。
BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
enum severity_level {
normal,
notification = 2,
warning,
error,
critical,
};
boost::log::sources::severity_logger_mt<severity_level> logger;
BOOST_LOG_SEV(logger, notification) << "hello, world";
如上代码将会产生两个日志记录。注意:日志记录并不是简单的一行日志文本。
- 属性(Attribute):属性是能够对每个日志记录进行特化处理的手段,在 Boost.Log 中属性被抽象为具有特定接口的函数对象。当其被被调用时,将产生属性值。
- 属性值(Attribute value):每个日志记录都有着一些特定的属性值。注意:属性值通过类型擦除的方式存储。
- 日志源(Log source):用户输入日志记录的地方。通常来说就是一个带有一些属性集合的日志(logger)对象。
- 日志池(Log sink):收集来自用户产生的所有日志记录,日志池定义了日志记录如何被存储和处理。
- 日志过滤器(Log filter):一种谓词(返回布尔值的函数
bool (attribute_value_set const&)),它接收一条日志记录,并决定该记录是否应继续进行后续处理或被丢弃。该谓词通常根据记录所附带的属性值来进行判断。 - 日志格式化器(Log formatter):将日志记录生成最终文本的函数对象。
- 日志核心(Logging core):日志核心维护着一个日志池列表,以及对所有日志源产生的日志记录应用过滤器。 它主要是被用来对 Boost.Log 进行配置,应用程序全局应当仅存在一个实例。
Boost.Process
在 C++ 标准库中,提供了 std::system() 的实现,用于调用外部应用程序,但它也存在一些缺点:安全性问题、平台依赖性、性能开销、错误处理困难以及缺乏控制。其中在应用开发中,比较头疼的就是错误处理,std::system() 返回一个整数值,表示命令的退出状态,这个值通常是 0 表示成功,非 0 表示失败。但是,要准确地处理各种可能的错误情况(例如命令不存在、执行失败等)比较困难。
Boost.Process 提供了跨平台的接口,使得代码在不同的操作系统上具有更好的可移植性。
同时,它还提供了更安全的执行外部程序的方式。它避免了直接将用户提供的字符串传递给 shell 执行,从而减少了安全漏洞的风险。它允许你以参数列表的形式传递命令和参数,而不是构建一个可能包含恶意代码的字符串。
Boost.Process 在原来 V1 版本的基础上,实现了 V2 版本,简化了接口,以及更正了之前的一些API设计方面的失误。
Boost.Signals2
Boost.Signals2库是一个管理信号和槽函数系统的实现。信号代表具有多个目标的回调,在相似系统中也称为发布者或事件。信号连接到一组槽函数,这些槽函数是回调接收器(也称为事件目标或订阅者),在“发出”信号时调用它们。
连接管理
- 通过
boost::signals2::connection断开连接
boost::signals2::connection c = sig.connect(HelloWorld());
std::cout << "c is connected\n";
sig(); // Prints "Hello, World!"
c.disconnect(); // Disconnect the HelloWorld object
std::cout << "c is disconnected\n";
sig(); // Does nothing: there are no connected slots
-
通过
signal的disconnect方法:void foo() { std::cout << "foo\n"; }
void bar() { std::cout << "bar\n"; }
boost::signals2::signal<void ()> sig;
sig.connect(&foo);
sig.connect(&bar);
sig();
// disconnects foo, but not bar
sig.disconnect(&foo);
sig(); -
依次还有
boost::signals2::shared_connection_block、boost::signals2::scoped_connection、slot::track,具体可查看帮助手册。
槽函数类型:
using OnClick = boost::signals2::signal<void (int x, int y)>;
using OnClickSlotType = OnClick::slot_type
// 比较优雅的方式还是将 OnClick 的操作隐藏在实现中
boost::signals2::connection Button::doOnClick(const OnClickSlotType & slot) {
return onClick.connect(slot);
}
信号返回值
查看帮助手册。