原文地址: http://blog.csdn.NET/xujiezhige/article/details/8652025
第一次使用boost库是因为网络编程,由于时间比较紧,没有时间每个库都学,所以前期想找个专门的boost库网络教程(以前自己就用过socket写过,但是为了跨平台,而且boost库这么好,还是趁早学吧)。终于在网上找到一个很好的boost库教程系列。http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio/?pg=1
- boost库IOS版本的framework下载和使用地址:https://github.com/mz2/boostoniphone。之所以用framework是因为IOS设备和IOS模拟器使用的boost库是不一样的,一个是嵌入式设备版本,另外一个就是MAC OS版本,为了解决IOS设备与模拟器之间的调试差异,使用framework最好不过了。
- resolver的异步查询(async_resolve)让我搞了1个小时,虽然教程上说根据说明文档很容易使用async_resolve,但是实际编写时就遇到问题了。
bug:异步完成句柄被调用时始终传入error。
但从网上查资料,基本跟我写的一样啊,没什么区别。最后各种尝试,终于找出里面的原因来了。
解决方法:io_service必须要在socket,resolver初始化之后才能调用run()函数,否则异步查询始终出错。 - scoped_ptr:确保指针的所有者只有一个(当然你不应该将原生指针赋给多个scoped_ptr对象),即scoped_ptr本身不能被scoped_ptr类型构造或者赋值。而且由于将原生指针封装成类,可就成了异常安全类型了。并且scoped_ptr很适合用于有多个分支的函数,例如一开始申请一块缓冲区,多个分支函数可能直接返回,在返回之前我们一般都需要删除这块内存,此时我们可以使用scoped_ptr去指向这块刚申请的内存。这样我们就不用显示释放了。这个方案相比于使用goto语句结构更清晰,更安全。
- scoped_array:它和scoped_ptr几乎一模一样,除了多提供了operator[]函数,使其能像一般数组一样访问对应元素。scoped_array一般用于当数组元素固定的时候(个人认为如果固定的话,除非每个元素大小很大,否则直接使用局部变量比较好)。动态的数组分配,如果对效率没有非常苛刻的要求的话,建议还是使用std::vector。
- shared_ptr
- 在看到boost部分源码的时候对其构造函数比较好奇,为了构造函数还使用偏特化模版函数。即
- template<typename T> class shared_ptr {
- public:
- template <class Y> explicit shared_ptr(Y* p);
- .....
- };
- boost::shared_ptr< void > p( new std::string( "HelloWorld" );
- 这种设计其实背后有很大文章。由于shared_ptr设计中也考虑到兼容以前代码,所以我们可以从shared_ptr获取原生指针,但如果用户使用原生指针删除了动态分配的对象怎么办?
我们可以采用这种模式:
- class A {
- public:
- virtual void sing()=0;
- protected:
- virtual ~A() {};
- };
- class B : public A {
- public:
- virtual void sing() {
- std::cout << "Do re mi fa so la";
- }
- };
基类的析构函数是protected,所以基类指针是不能调用delete。派生类的是public自然就可以删除了。有了上面的设计,在加上shared_ptr的模版参数和构造参数可以不同这个特点,就可以解决方面的问题了,如:
- boost::shared_ptr<A> createA() {
- boost::shared_ptr<A> p(new B());
- return p;
- }
通过此函数创建出来的shared_ptr,其get()返回的指针是无法被删除的(当然你强制转换除外)。所以可以放心的把shared_ptr::get()函数返回的指针给需要原生指针的函数使用。
- 在看到boost部分源码的时候对其构造函数比较好奇,为了构造函数还使用偏特化模版函数。即
- polymorphic_cast
这是一个dynamic_cast的特殊版,由于dynamic_cast对指针转换失败和引用转换失败结果不一致,polymorphic_cast决心将其改正,也就是当指针类型转换失败的时候也抛出异常,但是polymorphic_cast不能用于引用类型。个人感觉有点“拗口”。不过书中也提了利用将指针转换成引用来实现指针转换失败时采用像引用转换失败的策略(即抛出异常)。由于现在水平有限,不能很好地体会到大师用意。 - polymorphic_downcast
这是非常好的工具,一个在debug环境下按照dynamic_cast流程走,以方便调试。但是在release环境下按照static_cast流程走,提高效率。当然前提是你确保传入的类型按原本的意图是指传一种已知的类型,即这个模版函数适用于,原来强制类型转换的地方(特别是预防以后可能传入错误类型的情况)。 - numeric_cast
是个使用的工具,让我们平时粗心的转换得到更多安全的保障。 - lexical_cast
一个让字符串和其他类型之间的转换更“美好“的工具。原理类似与stringstream。用户自定义的类,只要满足operator<<就能被lexical_cast转换。如果满足operator>>就能接受lexical_cast的转换结果。 - BOOST_STATIC_CAST
一个能在编译阶段确定某模版参数是某一类型的宏定义。唉,我们日常生活自己编写模版类的实践太少,看来中国和最先进的C++水平还是有不少差距啊。 - checked_delete
一个能保证被delete的对象所属类,在该函数调用处,已经有完整信息。即编译器有类的足够信息,以可以正常调用该对象类的析构函数。这种情况很少,但是大师的任务是,杜绝一切可能,提供最牢靠的”防御“。 - noncopyable
一个在很多类框架中都能看到,而且自己也接触的模式,就是提供一个不可复制的基类。让派生类以私有形式(共有形式也可以,但是在设计角度不够好)派生该基类。以表达此类具有不可复制的属性。 - address_of
一个能确保取到变量地址的模版函数,及时这个变量所属的类重载了取址操作符(&),此函数也能够取到真正地址。 - enable_if, disable_if
一个能让某些模版函数或者类加入或者排除在候选重载函数中。牛,我只能说,大师做的事情已经跟我们不一个级别了。目前还没遇到过这种情况,但是我相信,如果没有看到《Beyond the C++ Standard Library: An Introduction to Boost》,一定会很迷茫。 - operator
operators头文件中包含了很多有便扩展操作符重载的解决方案,就像书中写的,如果我们提供operator<,那么我么应该提供operator<=,>=,>等操作符,但是其实我们发现,通过opertor<我们能够推出operator<=,operator>=,operator>等操作符,但是我们却往往忽略,或者怕出错误,以至于我们类的操作符重载不够“友好”,用户使用不能像预想的那样。opertors库,让这些依赖于主操作符重载的辅操作符重载更简单,而且更加概念化,系统化。通过派生于less_than_comparable<typename T>,我们就能实现比较,通过其他概念,我们将更加简单而且清晰的实现各类应该具备的操作符。 - regular expression
相信做过文本文件读取,或者各类工具的编程爱好者,一定对于正则表达式十分的向往(如果有高效,易用的正则表达式,那么很多应用将得心应手)。相信boost::regex可以给你带来希望。基本上是用使用regex需要3部分:需要被处理的源文本字符串,匹配结果,正则表达式。通过regex的三大算法(regex_match,regex_search,regex_replace),我们能实现各种应用,而且还有其他很多如regex_token_iterator等使用操作,让regex非常好用。但是regex是个很大的库,里面包含的知识和应用十分庞大,具体的还是需要参考document,这个章节只是一个很好的引导者。 - any
这个类提供了像shared_ptr一样的功能:能够包含任意类型。但是any不是一个模板类。所以我们可以在stl的容器中使用其作为类型参数,这样我们就可以实现在stl容器中包含任意类型的目的了。any中的any_cast是其精髓,想要访问any中的实例都需要这个接口去获得新的实例拷贝。