资源预览内容
第1页 / 共74页
第2页 / 共74页
第3页 / 共74页
第4页 / 共74页
第5页 / 共74页
第6页 / 共74页
第7页 / 共74页
第8页 / 共74页
第9页 / 共74页
第10页 / 共74页
亲,该文档总共74页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
.wd.BOOST应用初探 冯刚2011-8-41 背景BOOST是由c+标准化委员会成员参与开发的c+标准的准官方库,他是C+标准库的发动机。下一代C+标准C+0x的标准库很多来自于boost。Boost库覆盖了广泛的领域,从数学库到智能指针,从模板元编程库到预处理器库及语法词法分析,从线程到lambda表达式,等等。所有Boost库都具有宽松的许可证,确保库可以被自由使用于商用软件。2 功能2.1 概况Boost库涵盖了很广泛的领域,下面就常用的功能像智能指针,正则表达式,函数对象bind和function, 线程和线程池,时间日期,多索引容器,哈希容器,bimap,日志,内存池,模板元编程,循环缓冲区,tuple, 观察者模式signal2,网络通讯asio做一些介绍。2.2 功能2.2.1 智能指针2.2.1.1 概论smart pointers智能指针是存储“指向动态分配在堆上的对象的指针的对象。他们的行为很像 C+ 的内建指针,只是它们可以在适当的时候自动删除它们所指向的对象。智能指针在面对异常时有非常显著的作用,它们可以确保动态分配对象的完全析构。它们还可以用于跟踪多主人共享的动态分配对象。在概念上,智能指针可以看作拥有它所指向的对象,并因此在对象不再需要时负责将它删除。智能指针库提供了六个智能指针类模板:scoped_ptr简单的单一对象的唯一所有权。不可拷贝。scoped_array简单的数组的唯一所有权。不可拷贝。shared_ptr在多个指针间共享的对象所有权。shared_array在多个指针间共享的数组所有权。weak_ptr一个属于 shared_ptr 的对象的无所有权的观察者。intrusive_ptr带有一个侵入式引用计数的对象的共享所有权。这些模板被设计用来补充 std:auto_ptr 模板的缺乏。2.2.1.2 智能指针shared_ptrshared_ptr 类模板存储一个指向动态分配对象一般是用 C+ new-expression 生成的的指针。在最后一个 shared_ptr 所指向的对象被销毁或重置时,要保证它所指向的对象被删除。每一个 shared_ptr 都符合 C+ 标准库的 CopyConstructible 和 Assignable 的必要条件,并因此能够用于标准库容器。因为提供了比较操作,因此 shared_ptr 可以和标准库中的关联式容器一起工作。通常,一个 shared_ptr 不能正确地持有一个指向动态分配的数组的指针。关于那种用法请参见 shared_array。因为在实现中使用了引用计数,shared_ptr实例的循环引用不会被回收。例如,如果 main() 持有一个指向 A 的 shared_ptr, A 又直接或间接持有一个指回 A 的 shared_ptr,A 的使用计数是 2。最初的 shared_ptr 析构后将导致一个使用计数为 1 的 A 被悬挂。使用 weak_ptr 以“打破循环。这个类模板被 T 参数化,T 是被指向的对象的类型。shared_ptr 和它的大多数成员函数对于 T 没什么要求,允许它是一个不完整类型,或者为 void。对 T 有附加要求的成员函数 (constructors, reset) 都明确地记录在下面。只要 T* 能被隐式地转换到 U*,则 shared_ptr 就能被隐式地转换到 shared_ptr。特别是,shared_ptr 隐式转换到 shared_ptr,当 U 是 T 的一个可访问基类的时候,还能转换到 shared_ptr,以及转换到 shared_ptr。惯用手法由于智能指针是线程安全的,建议在代码里只为一个对象生成单一的shared_ptr,在多线程环境中传递参数时使用weak_ptr,这样当shared_ptr被析构,weak_ptr也会得到通知,变为无效,这样可以有效地防止野指针,同时也防止了潜在的循环引用,无法释放对象的问题。shared_ptr spA = shared_ptr(new A);int func(weak_ptr wpA)If(!wpA.expired)/正常处理逻辑shared_ptr spA = wpA.lock();/Use spAelse/智能指针已被其他线程释放func(spA);2.2.1.3 智能指针weak_ptr简介weak_ptr是Boost智能指针shared_ptr的一个重要伙伴。它允许打破循环依赖。另外,它还可以处理一个非常常见的问题悬空指针。当销毁最后一个智能指针shared_ptr,它会释放掉共享的资源。通过使用智能指针weak_ptr,这方面的信息会传播给所有观察该共享资源的智能指针weak_ptr,通过weak_ptr可以知道该共享资源已经释放,这意味着不会发生无意间访问无效指针的情形。这就是观察者模式的一个特例,也就是说,当销毁资源的时候,就会通知所有对资源感兴趣的weak_ptr,通过调用weak_ptr.expired(),当返回值为true时,就表示该共享资源已经释放了。weak_ptr 类模板存储一个引向已被 shared_ptr 管理的对象的 weak reference弱引用。为了访问这个对象,一个 weak_ptr 可以利用 shared_ptr 的构造函数或成员函数 lock 转换为 shared_ptr。当最后一个指向对象的 shared_ptr 消失,而对象也被删除后,从一个引向已被删除对象的 weak_ptr 实例获取 shared_ptr 的企图就会失败:构造函数会抛出一个 boost:bad_weak_ptr 类型的异常,而 weak_ptr:lock 会返回一个 empty shared_ptr。每一个 weak_ptr 都符合 C+ 标准库的 CopyConstructible 和 Assignable 的必要条件,并因此能够用于标准库容器。因为提供了比较操作,因此 weak_ptr 可以和标准库中的关联式容器一起工作。weak_ptr 的操作绝不会抛出异常。这个类模板被 T 参数化,T 是被指向的对象的类型。相对于 shared_ptr,weak_ptr 提供了一个非常有限的操作子集,因为在多线程程序中访问它所存储的指针是非常不安全的,甚至有时在一个单线程程序中也是不安全的也就是说,它可能引起未定义行为。姑且假设 weak_ptr 有一个返回 raw pointer裸指针的 get 成员函数,考虑下面这个无辜的代码片段:shared_ptr p(new int(5);weak_ptr q(p);/ some time laterif(int * r = q.get() / use *r设想在 if 之后,但是又恰恰在 r 被使用之前,另一个线程执行了语句 p.reset()。这样 r 就成了一个 dangling pointer悬挂指针。解决这个问题的方案是从 q 创立一个临时的 shared_ptr:shared_ptr p(new int(5);weak_ptr q(p);/ some time laterif(shared_ptr r = q.lock() / use *r这样,r 就持有一个引向 q 所指向的对象的引用。即使在其它线程中执行了 p.reset(),那个对象也会继续活着,直到 r 离开作用域或者被 reset。通过获得一个指向这个对象的 shared_ptr,我们可以有效地保住它不被析构。2.2.2 正则表达式xpressive 是一个先进的、面向对象的、用于C+的正则表达式模板库。正则表达式可以以字符串方式编写并在运行期分析,也可以以表达式模板方式编写并在编译期分析。正则表达式可以相互引用,或者递归引用其本身,你就可以用它们来构建任意复杂的语法。它与Boost.Regex库的区别就是无需编译,全模板库。如果你要在C+中处理文本,通常你有两个不相交的选项:正则表达式引擎或语法分析生成器。正则表达式引擎(如 Boost.Regex)更为强大和灵活;文本的模式以字符串方式表示,可以在运行期指定。但是,这意味着语法错误同样要到运行期才能被检测。另外,正则表达式不适合于高级的文本处理任务,如匹配平衡的、嵌套的标签。那些任务传统上都是由语法分析生成器(如 Spirit 语法分析器框架)来处理的。这些工具更为强大,但不够灵活。它们通常不允许你随时随意地修改你的语法规则。此外,它们不具备正则表达式的完全回溯语义,对于某些类型的模式来说,这样对作者更具有挑战性。将这两种方法无缝地集合到一起,在C+的文本处理世界中占据了独特的优势。通过 xpressive,你可以选择更象使用 Boost.Regex 那样去使用它,将正则表达式表示为字符串。或者你也可以象使用 Spirit 那样使用它,将你的 regexes 写为C+表达式,获得一种专用于文本处理的嵌入式语言所带来的所有好处。更重要的是,你可以混用这两种方式,从而获得两者的好处,对于那些要静态绑定的正则表达式编写正则表达式语法 - 由编译器进展硬编码和语法检查 - 其它的则动态绑定并在运行期指定。这些正则表达式可以相互递归地引用,在以前的正则表达式不能进展模式匹配的字符串中进展模式匹配。Xpressive 是一个只含头文件的模板库,这意味着你不需要修改你的构建脚本或链接任何独立的lib文件就可以使用它。你所要做的就是 #include 。如果你只使用静态 regexes,你可以只包含 xpressive_static.hpp 以提高编译速度。同样,如果你方案只使用动态regexes,则可以只包含 xpressive_dynamic.hpp。表28.1.xpressive的工具箱Tool 工具 Description 说明 basic_regex 含有一个已编译的正则表达式。basic_regex 是xpressive之中最重要的类型。你用xpressive做的任何事情都要从创立一个类型为 basic_regex 的对象开场。 match_results, sub_match match_results 含有 regex_match() 或 regex_search() 操作的结果。它就象一个存有 sub_match 对象的向量。一个 sub_match 对象含有一个已标记的子表达式(在Perl中又称为后向引用)。 根本上,它只是
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号