1. 【转载网友转载的 不过不知道原作者地址】
  2.  
  3. Boost入门向导
  1. 简介:
    boost是一套开源的、高度可移植的C++模板库。它由C++标准委员发起,且里面很多组件有望成为下一代的C++标准库,其地位将会与STL一样。
    boost库的英文站点是http://www.boost.org。
    如果上个页面不能访问,可以看http://boost.c-view.org,它是Boost镜像。
    boost按功能分为:字符串、容器、算法、迭代器、数据结构、内存管理、多线程、IO等。其中字符串组中的正规表达式可以与POSIX APIPerl语言处理正则表达式的功能相媲美;多线程组件不比java的多线程难用;内存管理组件如果能合理使用可以杜绝内存泄露,而其效率更是与垃圾收集机制不可同日而语。
    boost的接口(或concept)完全与STL兼容,它在实现上使用了很多STL功能,它本身的组件也可以作为STL容器及算法的元素,所以有使用上,感觉不出是两个类库,我们可以当成是一个类库来使用就行了。只是boost库是在boost::名字空间里。
    而我个人最喜欢的一点是,boost的源码可读性非常高,非不得已它很少用宏,且不会象某些STL的实现一样,到处都是下划线开头的变量。
  2.  
  3. 下载与安装:
    boost成为标准库后,以下步骤就可以省略了,现在要用boost,还得亲自动手。
    下载:
    打开boost主页,点击Getting StartedàDownloadàdownload releases from SourceForge,目前最新版本是boost_1_31_0.tar.bz2。然后再在同一个页面中下载boost-1.31.0-regex-patch-20040503.zip,这是一个补丁。
    下载之后,X/boost_1_31_0/ index.htm是一个本地的文档目录。
    安装:
    大多数boost组件只要直接包含相应头文件就可以使用[1]。但如果你用到date_timefilesystemgraphpythonregexsignalstestthread 等组件,则要要编译成相应的静态或动态库。
    新版本的boost在所有平台下统一使用jam完成编译与部署,并且boost还特别特化了一个jam版本bjam。这里以1.31.0版本为例,编译所有的boost库:
    执行boost源码发布包中的X/boost_1_31_0/tools/build/jam_src下的build.batbuild.bat将自动在系统中选择一个编译器,并在bin.xxxx目录下生成jambjam等工具。
    生成bjam后,配置好命令行编译环境。并用bjam解释(boostsrc)/下的jam文件即可编译并部署。其参数繁多,这里不一一列出,见X/boost_1_31_0/boost_1_31_0/more/getting_started.html #Build_Install。
    String and text processing:
    提供了字符串的操作功能,大概分为五个组件。但要注意的是,某些组件效率上可能会有问题,比如字符串与基本类型的相互转换、格式化等,它们的实现是先把输入参数转化为STL的字符流,然后通过字符流转换为用户想要的类型输出(从这一点也可以看出,可以相互转换的类型只限于字符流可接受的那几类,字符流使用与可接受类型与io流基本一样)。
    组件 描述
    lexical_cast 字符串与其它类型的相互转换
    format 格式化字符
    regex 正则表达式
    spirit 字符串分析框架。用inlineC++写成的EBNF语法。
    tokenizer 按位移或字符提取字符串
    lexical_cast
    很多时候,我们想要把字符串与其它类型相互转换,而使用标签的C库,比如atoi,itoa等有时会很麻烦,而且难以记住所有这些函数,使用lexical_cast做这种事情则非常之简单而安全。例子如下:
    #include <boost/lexical_cast.hpp>
  4.  
  5. void test_lexical_cast()
    {
    std::string strNember = boost::lexical_cast<std::string>(123);
    int a = boost::lexical_cast<int>("123");
    double b = boost::lexical_cast<double>("123.456");
    }
  6.  
  7. 要注意的是,test_lexical_cast里的最后两句在VC6.0下不能通过编译。
  8.  
  9. format
    format的使用与一般的C格式化函数要灵活的多,而且它提供了多种语言风格的格式化。format其实是一个仿函数,查看源代码有以下的定义:
    typedef basic_format<char > format;
    format要真正格式化的参数是通过operator%来传递给函数对象的。下面是一个简单的例子:
    #include <boost/format.hpp>
    std::cout <<
    boost::format("writing %1%, x=%2% : %3%-th try") % "toto" % 40.23 % 50;
  10.  
  11. format生成的对象可以直接入到输出流,要生成一个字符串,我们可以这样:
    std::string str = boost::lexical_cast<std::string>(
    boost::format("%1% %2% %3% %2% %1% /n") % "a" % "b" % "c"
    );
    这里生成的字符串是:"abcba /n"(%1%对应的参数是字符a,%2%对应的参数是字符b,%3%对应的参数是字符c)。
    regex:
    要分析一个字符串是否符合某种语法规则是一件很烦人而且容易出错的事,boost::regex组件实现了这种分析功能,我们就不用自己去分析了。
    语法分析通常使用正则表达式,regex正是通过接受一个正则表达式字符串作为参数,来分析给定的字符串是否符合某种语法规则的。
    下面这个例子字符串"abcd"是否符合表达式 /d{4}[- ]){3}/d{4}:
    #include<boost/regex.hpp>
    std::string s("abcd");
    static const boost::regex e("(//d{4}[- ]){3}//d{4}");
    if(boost::regex_match(s, e))
    std::cout << "match /n";
    else
    std::cout << "not match /n";
  12.  
  13. 我们还可以分析一篇文档,提取只符合表达式的内容,比如,有一篇xml文档,超级链接的地址是放在属性href中,我想要提取所有超链接的地址可以这样写表达式:
    boost::regex expression("//s+href//s*=//s*/"([^/"]*)/"");
    完整的代码如下:
    void test_regex_split()
    {
    using namespace boost;
    regex expression("//s+href//s*=//s*/"([^/"]*)/"");
    // 假如文档的内容如下:
    std::string s = "<a href=/"index.html/"><img src=/"logo.gif/"></a>";
    std::vector<std::string> result; // 用于保存结果
    // 把字符串s按表达式expression分割,并把结果放到result中
    regex_split(std::back_inserter(result), s, expression);
    for (std::vector<std::string>::iterator it = result.begin(); it != result.end(); ++it)
    std::cout << *it;
    std::cout << std::endl;
    }
  14.  
  15. 注意,要用regex是需要编译成相应的库的。
    tokenizer
    tokenizer组件提供了一种非常弹性且容易使用的方法来分割字符串。它的使用比较简单,下面两个例子,例子一是把"hello, word!"分成7+5两个字符,例子二是把字符串按分隔符符分隔开:
    #include <boost/tokenizer.hpp>
    void test_tokenizer1()
    {
    std::string s = "hello, word!";
  16.  
  17. int offsets[] = {7, 5};// 分成两串,一串7个字符,一串5个
    boost::offset_separator f(offsets, offsets+2);
  18.  
  19. typedef boost::tokenizer<boost::offset_separator> SeparatoTokenizer;
    SeparatoTokenizer tok(s, f);
    for(SeparatoTokenizer::iterator it = tok.begin(); it != tok.end(); ++it)
    {
    std::cout << "<" << *it << "> " << '/t';
    }
    std::cout << std::endl;
  20.  
  21. void test_tokenizer2()
    {
    std::string str = ";;Hello|world||-foo--bar;yow;baz|";
    boost::char_separator<char> sep("-;|"); //分隔符
  22.  
  23. typedef boost::tokenizer<boost::char_separator<char> > CharTokenizer;
    CharTokenizer tokens(str, sep);
    for (CharTokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
    {
    std::cout << "<" << *tok_iter << "> " << '/t';
    }
    std::cout << std::endl;
    }
  24.  
  25. Containers
    boost中的容器主要是作为STL容器的一个补充。静态数组、多维数组的使用跟一般的C语法数组差不多,但作为容器,它提供了STL中的很多concept(比如iterater),所以可以使用STL算法来访问它们。dynamic_bitset 是一种动态的bisetproperty map是把key对象影射到value对象,所有具有下标操作的类型都可以作为它的元素,对property map的需求来源于BGL
    组件 描述
    array 符合STL容器语意4的静态数组
    multi_array 多维数组,而且可以与array适配(前提是有共同的边界)
    dynamic_bitset 一种可以在运行时改变大小的bitset
    property map 一套可以把key对象影射到value对象的类与全局函数
    graph 图容器,即BGL[2]
  26.  
  27. array
    STL提供了一套接口(或concept),用于处理不同容器的算法。但普通数组却因为没有相应的接口[3]而不能很好的配合这些算法的使用。
    boost中的array具有静态数组的效率与功能,且提供了STL容器的各种接口。
  28.  
  29. multi_array
    使用STL,如果要声明一个二元的整数数组,我们可以这样:
    std::vector<std::vector<int>>
    如果要三维,四维,N维,还使用这种方式?先不说这种代码有多恶心,做起来有多麻烦,只要能完成工作就行了,但很多时候偏偏不能,比如在效率上有要求的时候(想一想vector的实现,这种动态增加如果发生在N维数组上)。而使用普通的数组,又不能很好配合STL算法,这在上面已经提过了。
    boostmulti_array组件提供了标准库的接口,而且功能与效率上与普通数组一样。下面是一个该组件的简单例子:
    #include "boost/multi_array.hpp"
  30.  
  31. void test_array ()
    {
    // 创建一个 3 x 4 x 2 的3D数组
    boost::multi_array<double, 3> A(boost::extents[3][4][2]);
  32.  
  33. typedef boost::multi_array<double, 3>::index index;
  34.  
  35. // 给数组的元素赋值
    int values = 0;
    for(index i = 0; i != 3; ++i)
    for(index j = 0; j != 4; ++j)
    for(index k = 0; k != 2; ++k)
    A[i][j][k] = values++;
  36.  
  37. // 输出数组的元素值
    for(i = 0; i != 3; ++i)
    for(index j = 0; j != 4; ++j)
    for(index k = 0; k != 2; ++k)
    std::cout << A[i][j][k] << "/t";
  38.  
  39. std::cout << std::endl;
    }
  40.  
  41. dynamic_bitset
    boostdynamic_bitset几乎等价于std::bitest,不同的是,dynamic_bitset的大小是可以在运行时改变的。该组件在使用VC6.0下编译不过。
  42.  
  43. property map
    property map定义了一套接口把key对象影射到相应的value对象,所有具有下标操作的类型(比如指针、数组、std::map等)都可以作为它的元素。对property map的需求最初来源于BGL
    property map的接口包含三个全局函数get(), put(), operator[]。
    下面是property map的使用例子,例子中使用到了boost::associative_property_map类,但其实使用其它的具有下标操作的类型也一样可以:
    #include <boost/property_map.hpp>
    template <typename AddressMap>
    void foo(AddressMap address)
    {
    typedef typename boost::property_traits<AddressMap>::value_type value_type;
    typedef typename boost::property_traits<AddressMap>::key_type key_type;
  44.  
  45. value_type old_address, new_address;
    key_type fred = "Fred";
    old_address = boost::get(address, fred);
    new_address = "384 Fitzpatrick Street";
    boost::put(address, fred, new_address);
    address["Joe"] = "325 Cushing Avenue";
    }
  46.  
  47. void test_property_map()
    {
    typedef std::map<std::string, std::string> NameAddrMap;
    NameAddrMap name2address;
    boost::associative_property_map<NameAddrMap> address_map(name2address);
    name2address.insert(std::make_pair(std::string("Fred"),
    std::string("710 West 13th Street")));
    name2address.insert(std::make_pair(std::string("Joe"),
    std::string("710 West 13th Street")));
  48.  
  49. foo(address_map);
    for (NameAddrMap::iterator it = name2address.begin(); it != name2address.end(); ++it)
    std::cout << it->first << ": " << it->second << "/n";
    }
  50.  
  51. Data structures
    组件 描述
    any 可以接受不同的类型的值,当一个容器要接受不同的类型元素时用它会很方便
    compressed_pair
    std::pair相似,但如果其中一个元素为空类时,会比std::pair更节省空间
    tuple
    可以定义一个或多个元素的结构,作为函数返回值时会很方便
    tuple
    如果说,pair是可以定义有两个元素的结构体,那么tuple是可以定义110元素的结构体。tuple的大部分定义是在boost::tuples::名字空间内(除了某些很通用的是在boost::内)
    访问tuple元素可以通过两个方式,
    t.get<N>()
    或者
    get<N>(t)
    这里,t是一个tuple实例。(第一种方法在VC6.0下编译不过)
  52.  
  53. 它的使用例子如下:
    #include "boost/tuple/tuple.hpp"
    void test_tuple()
    {
    // 最多可以10元素
    boost::tuples::tuple<char, double, std::string> triples('a', 2.4, "hello");
    std::cout << boost::tuples::get<0>(triples) << '/t'
    << boost::tuples::get<1>(triples) << '/t'
    << boost::tuples::get<2>(triples) << std::endl;
    }
  54.  
  55. Memory
    Memory中的组件比较通用,pool组件提供的内存分配可以使指针为作一个真正的原生指针,而又不用管理内存。智能指针要比std::auto_prt的好,但并非不可以代替(之前网上有编文章评论没有loki提供智能指针的好用,而且KFC也有相应的组件。)
    组件 描述
    pool 内存池管理
    smart_ptr 智能指针,总共提供了6种类型
  56.  
  57. pool
    pool是什么?
    pool是一套非常高效的内存分配方案。
    为什么要使用pool?
    使用pool分配内存得到的指针是真正的指针,这意味着,使用者可以对内存有更多的控制(相对于智能指针)。使用pool接口,你可以选择只运行对象的析构函数或只简单地对指向对象的指针回收。pool会保证没有内存泄漏。
    什么时候使用pool?
    当有大量小对象分配与回收,而又不想去亲自去管理内存时。
  58.  
  59. 总之,当你想要高效率的方式去操纵内存时用它会带来很多好处。
  60.  
  61. pool 提供了四个比较通常的组件:poolobject_poolsingleton_poolpool_alloc
    下面给出前两个组件的简单使用样例:
    #include <boost/pool/pool.hpp>
    void test_pool_BaseType()
    {
    boost::pool<> p(sizeof(int));
    for (int i = 0; i < 5; ++i)
    {
    int* const t = (int*)p.malloc();
    *t = i;
    std::cout << *t << '/t';
    }
    std::cout << std::endl;
    }// on function exit, p is destroyed, and all malloc()'ed ints are implicitly freed
  62.  
  63. #include <boost/pool/object_pool.hpp>
    class X {};
    void test_pool_object()
    {
    boost::object_pool<X> p;
    for (int i = 0; i < 10000; ++i)
    {
    X* const t = p.construct();
    // to do
    }
    }
  64.  
  65. 使用pool,我们可以不用管内存释放。当然,如果你想自己释放内存,可以使用void destroy(element_type * p)成员函数。这里element_type是传进来的模板参数类型。
    object_pool是使用内存池管理内存,如果频繁分配和删除相同类型的对象,object_pool要比直接调用new,delete高出几个数量级。
    smart_ptr
    STLstd::auto被很多人认为是标准库的一个缺陷,其实并不是这样,只是因为std::auto提供的功能不够丰富摆了,它缺少对引用数和数组的支持,并且,std::auto_ptr在被复制的时候会传输所有权。因为缺少引用,所以对象没有共享所有权,结果就不可以跟其它STL组件(比如容器)很好的配合使用。
    boost提供的智能指针正好补充了以上功能,比较通用的组件有:
    scoped_ptr,用于处理单个对象的唯一所有权。
    scoped_array,与scoped_ptr类似,但是用来处理数组的。
    shared_ptr,允许共享对象所有权。
    shared_array,允许共享数组所有权。
  66.  
  67. 其它:
    date_time
    一套处理日期与时间的组件,在它之前,我没有发现有类似的C++库,每次处理时间日期时,都觉繁琐且容易出错,现在用它,就再也不用记浮点数0是哪年哪月哪日了。使用date_time要编译boost代码成相应的库。它的使用比较简单,下面给出例子:
    #include <boost/date_time/gregorian/gregorian.hpp>
    #include <boost/date_time/posix_time/posix_time.hpp>
  68.  
  69. void test_data_time()
    {
    using namespace boost::gregorian;
  70.  
  71. date today = day_clock::local_day();
    std::string strToday = to_simple_string(today);
    std::cout << "today is: " << strToday << std::endl;
  72.  
  73. using namespace boost::posix_time;
  74.  
  75. date d(2004, May, 1);
    ptime t1(d, hours(5)+minutes(4)+seconds(2)+millisec(1));
    ptime t2 = t1 - hours(5) - minutes(4) - seconds(2) - millisec(1);
    time_duration td = t2 - t1;
  76.  
  77. std::cout << to_simple_string(t2) << " - "
    << to_simple_string(t1) << " = "
    << to_simple_string(td) << std::endl;
    }
  1. [1] 这里是大多数而不是全部,是因为boost不象STL那样已经标准化,主流的编译器要么提供本地版本要么完全支持开源版本。而目前boost的开源版本可能不是每一个编译器都能完全支持;另一个与STL不同的是,boost某些库需要编译成相应的静态库与动态库才可以用。
    [2] Boost Graph Libraryboost 图形库,一套用于图形的容器与算法组件)
    [3] 其实普通数组的指针也是可以看作为一种简单的iterator

Boost入门的更多相关文章

  1. Linux上安装使用boost入门指导

    Data Mining Linux上安装使用boost入门指导 获得boost boost分布 只需要头文件的库 使用boost建立一个简单的程序 准备使用boost二进制文件库 把你的程序链接到bo ...

  2. vs 2005 使用 boost regex

    第一步: Boost 入门及其VS2005下编译boost库  boost.regex库安装指南  深入浅出之正则表达式(一)  C++中三种正则表达式比较(C regex,C ++regex,boo ...

  3. Boost(1.69.0) windows入门(译)

    目录 Boost windows入门 1. 获得Boost源代码 2. Boost源代码组织 The Boost Distribution 3. 仅用头文件的库 Header-Only Librari ...

  4. Boost::Asio入门剖析

    Boost::Asio可以在socket等I/O对象上执行同步或异步操作,使用Boost::Asio前很有必要了解Boost::Asio.你的程序以及它们交互的过程. 作为一个引导的例子,我们思考一个 ...

  5. Boost库学习之旅入门篇

    学习及使用Boost库已经有一段时间了,Boost为我的日常开发中带来了极大的方便,也使得我越来越依赖于boost库了.但boost功能太多,每次使用还是得翻看以前的 资料,所以为了以后可以更方便的使 ...

  6. boost 的函数式编程库 Phoenix入门学习

    这篇文章是我学习boost phoenix的总结. 序言 Phoenix是一个C++的函数式编程(function programming)库.Phoenix的函数式编程是构建在函数对象上的.因此,了 ...

  7. boost库之graph入门

    #include <boost/graph/undirected_graph.hpp> #include <boost/graph/adjacency_list.hpp> us ...

  8. boost多线程入门介绍

    :first-child { margin-top: 0px; } .markdown-preview:not([data-use-github-style]) h1, .markdown-previ ...

  9. Win7 VS2017 Boost Python入门

    闲来无事想练习下用Python作为游戏脚本绑定到C++,网上搜了下,Python文档有些例子,但是太过复杂,gayhub无意中看到有人用Boost Python绑定,简单粗暴,省时省力,记录备忘. 写 ...

随机推荐

  1. Git命令--保存用户名和密码

    使用git各项操作时,总是会出现输入密码的弹窗,且需要多次输入,很是繁琐,通过git命令可以记住密码,避免多次操作. 一.创建保存密码的文件 1.在home文件夹,一般是 C:\Documents a ...

  2. Node.js | 你的物联网系统,有个管家待认领

    很多时候,专业的事情都要交给专业的人来做,才会更放心. 例如买了套房,交房装修完毕,欢天喜地入住后,房子的日常养护和维护之类的事情,都由谁来负责呢? 物业呗~买了房子就自然需要房子所在小区提供的物业服 ...

  3. ECLIPSE 取消自动更新

    经常遇到一开eclipse 时,一直很卡的问题,发现是它一直尝试联网更新东西 ,如maven 所以解决办法  , eclipse 取消自动更新的方法: 1. window --> prefere ...

  4. 再回首win98

    因为一个软件只能运行在win98上,所以上个win98虚拟机. 下载的是经典的Win98.SE.iso 307M. 真是小巧呀,感慨现在的win8.1的3.69G,真是没法比. 原来是没有用过老古董的 ...

  5. oracle数据类型及操作

    1. Oracle字符串操作 1.1 字符串类型 Ø CHAR和VARCHAR2类型 l CHAR存放定长字符,如果数据存不满指定长度则用空格补齐,CHAR类型浪费空间换取查询时间的缩短. l VAR ...

  6. HDU1043 八数码(BFS + 打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...

  7. pat甲级1044二分查找

    1044 Shopping in Mars(25 分) Shopping in Mars is quite a different experience. The Mars people pay by ...

  8. 新建snmp模型总结

    1.在DeviceType.xml中添加新的模块 2.在modellidx.json中添加路径关联 3.添加定义模型 4.定义model.xml注意: 5.定义collect.xml注意:

  9. 工作流性能优化(敢问activiti有扩展性?)(2)

    2015/4/17 粗略看了activiti的sql的,在ativity engine包里边: 没什么头绪,先用excel记录数据量少的时候本机的性能情况:   不打印hibernate的sql:一刷 ...

  10. Android(java)学习笔记94: SurfaceView使用

    1. SurfaceView简介    在一般的情况下,应用程序的View都是在相同的GUI线程(UI主线程)中绘制的.这个主应用程序线程同时也用来处理所有的用户交互(例如,按钮单击或者文本输入). ...