Boost入门

                                                【转载网友转载的  不过不知道原作者地址】

Boost入门向导
简介:boost是一套开源的、高度可移植的C++模板库。它由C++标准委员发起,且里面很多组件有望成为下一代的C++标准库,其地位将会与STL一样。boost库的英文站点是http://www.boost.org。如果上个页面不能访问,可以看http://boost.c-view.org,它是Boost镜像。boost按功能分为:字符串、容器、算法、迭代器、数据结构、内存管理、多线程、IO等。其中字符串组中的正规表达式可以与POSIX API和Perl语言处理正则表达式的功能相媲美;多线程组件不比java的多线程难用;内存管理组件如果能合理使用可以杜绝内存泄露,而其效率更是与垃圾收集机制不可同日而语。boost的接口(或concept)完全与STL兼容,它在实现上使用了很多STL功能,它本身的组件也可以作为STL容器及算法的元素,所以有使用上,感觉不出是两个类库,我们可以当成是一个类库来使用就行了。只是boost库是在boost::名字空间里。而我个人最喜欢的一点是,boost的源码可读性非常高,非不得已它很少用宏,且不会象某些STL的实现一样,到处都是下划线开头的变量。

下载与安装:当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_time、filesystem、graph、python、regex、signals、test、thread 等组件,则要要编译成相应的静态或动态库。新版本的boost在所有平台下统一使用jam完成编译与部署,并且boost还特别特化了一个jam版本bjam。这里以1.31.0版本为例,编译所有的boost库:执行boost源码发布包中的X/boost_1_31_0/tools/build/jam_src下的build.bat,build.bat将自动在系统中选择一个编译器,并在bin.xxxx目录下生成jam,bjam等工具。生成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	字符串分析框架。用inline的C++写成的EBNF语法。tokenizer	按位移或字符提取字符串lexical_cast:很多时候,我们想要把字符串与其它类型相互转换,而使用标签的C库,比如atoi,itoa等有时会很麻烦,而且难以记住所有这些函数,使用lexical_cast做这种事情则非常之简单而安全。例子如下:#include <boost/lexical_cast.hpp>

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"); }

要注意的是,test_lexical_cast里的最后两句在VC6.0下不能通过编译。

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; 

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";elsestd::cout << "not match /n";

我们还可以分析一篇文档,提取只符合表达式的内容,比如,有一篇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;}

注意,要用regex是需要编译成相应的库的。tokenizer:tokenizer组件提供了一种非常弹性且容易使用的方法来分割字符串。它的使用比较简单,下面两个例子,例子一是把"hello, word!"分成7+5两个字符,例子二是把字符串按分隔符符分隔开:#include <boost/tokenizer.hpp>       void test_tokenizer1()    {        std::string s = "hello, word!";

        int offsets[] = {7, 5};// 分成两串,一串7个字符,一串5个        boost::offset_separator f(offsets, offsets+2);

        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;    }

void test_tokenizer2(){std::string str = ";;Hello|world||-foo--bar;yow;baz|";boost::char_separator<char> sep("-;|"); //分隔符

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;}

Containers:boost中的容器主要是作为STL容器的一个补充。静态数组、多维数组的使用跟一般的C语法数组差不多,但作为容器,它提供了STL中的很多concept(比如iterater),所以可以使用STL算法来访问它们。dynamic_bitset 是一种动态的biset。property map是把key对象影射到value对象,所有具有下标操作的类型都可以作为它的元素,对property map的需求来源于BGL。组件	描述array	符合STL容器语意4的静态数组multi_array	多维数组,而且可以与array适配(前提是有共同的边界)dynamic_bitset	一种可以在运行时改变大小的bitset。property map	一套可以把key对象影射到value对象的类与全局函数graph	图容器,即BGL[2]

array:STL提供了一套接口(或concept),用于处理不同容器的算法。但普通数组却因为没有相应的接口[3]而不能很好的配合这些算法的使用。boost中的array具有静态数组的效率与功能,且提供了STL容器的各种接口。

multi_array:使用STL,如果要声明一个二元的整数数组,我们可以这样:std::vector<std::vector<int>>如果要三维,四维,N维,还使用这种方式?先不说这种代码有多恶心,做起来有多麻烦,只要能完成工作就行了,但很多时候偏偏不能,比如在效率上有要求的时候(想一想vector的实现,这种动态增加如果发生在N维数组上)。而使用普通的数组,又不能很好配合STL算法,这在上面已经提过了。而boost的multi_array组件提供了标准库的接口,而且功能与效率上与普通数组一样。下面是一个该组件的简单例子:#include "boost/multi_array.hpp"

void test_array (){    // 创建一个 3 x 4 x 2 的3D数组    boost::multi_array<double, 3> A(boost::extents[3][4][2]);

    typedef boost::multi_array<double, 3>::index    index;

    // 给数组的元素赋值    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++;

    // 输出数组的元素值    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";

    std::cout << std::endl;}

dynamic_bitset:boost的dynamic_bitset几乎等价于std::bitest,不同的是,dynamic_bitset的大小是可以在运行时改变的。该组件在使用VC6.0下编译不过。

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;

    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";}

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")));

    foo(address_map);    for (NameAddrMap::iterator it = name2address.begin(); it != name2address.end(); ++it)        std::cout << it->first << ": " << it->second << "/n";}

Data structures:组件	描述any	可以接受不同的类型的值,当一个容器要接受不同的类型元素时用它会很方便compressed_pair与std::pair相似,但如果其中一个元素为空类时,会比std::pair更节省空间tuple可以定义一个或多个元素的结构,作为函数返回值时会很方便tuple:如果说,pair是可以定义有两个元素的结构体,那么tuple是可以定义1到10元素的结构体。tuple的大部分定义是在boost::tuples::名字空间内(除了某些很通用的是在boost::内)访问tuple元素可以通过两个方式,t.get<N>()或者get<N>(t)这里,t是一个tuple实例。(第一种方法在VC6.0下编译不过)

它的使用例子如下:#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;}

Memory:Memory中的组件比较通用,pool组件提供的内存分配可以使指针为作一个真正的原生指针,而又不用管理内存。智能指针要比std::auto_prt的好,但并非不可以代替(之前网上有编文章评论没有loki提供智能指针的好用,而且KFC也有相应的组件。)组件	描述pool	内存池管理smart_ptr	智能指针,总共提供了6种类型

pool:pool是什么?pool是一套非常高效的内存分配方案。为什么要使用pool?使用pool分配内存得到的指针是真正的指针,这意味着,使用者可以对内存有更多的控制(相对于智能指针)。使用pool接口,你可以选择只运行对象的析构函数或只简单地对指向对象的指针回收。pool会保证没有内存泄漏。什么时候使用pool?当有大量小对象分配与回收,而又不想去亲自去管理内存时。

总之,当你想要高效率的方式去操纵内存时用它会带来很多好处。

pool 提供了四个比较通常的组件:pool、object_pool、singleton_pool、pool_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

#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    }}

使用pool,我们可以不用管内存释放。当然,如果你想自己释放内存,可以使用void destroy(element_type * p)成员函数。这里element_type是传进来的模板参数类型。object_pool是使用内存池管理内存,如果频繁分配和删除相同类型的对象,object_pool要比直接调用new,delete高出几个数量级。smart_ptr:STL的std::auto被很多人认为是标准库的一个缺陷,其实并不是这样,只是因为std::auto提供的功能不够丰富摆了,它缺少对引用数和数组的支持,并且,std::auto_ptr在被复制的时候会传输所有权。因为缺少引用,所以对象没有共享所有权,结果就不可以跟其它STL组件(比如容器)很好的配合使用。boost提供的智能指针正好补充了以上功能,比较通用的组件有:scoped_ptr,用于处理单个对象的唯一所有权。scoped_array,与scoped_ptr类似,但是用来处理数组的。shared_ptr,允许共享对象所有权。shared_array,允许共享数组所有权。

其它:date_time:一套处理日期与时间的组件,在它之前,我没有发现有类似的C++库,每次处理时间日期时,都觉繁琐且容易出错,现在用它,就再也不用记浮点数0是哪年哪月哪日了。使用date_time要编译boost代码成相应的库。它的使用比较简单,下面给出例子:#include <boost/date_time/gregorian/gregorian.hpp>#include <boost/date_time/posix_time/posix_time.hpp>

void test_data_time(){    using namespace boost::gregorian;

    date today = day_clock::local_day();    std::string strToday = to_simple_string(today);    std::cout << "today is: " << strToday << std::endl;

    using namespace boost::posix_time;

    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;

    std::cout << to_simple_string(t2) << " - "       << to_simple_string(t1) << " = "       << to_simple_string(td) << std::endl;}
[1] 这里是大多数而不是全部,是因为boost不象STL那样已经标准化,主流的编译器要么提供本地版本要么完全支持开源版本。而目前boost的开源版本可能不是每一个编译器都能完全支持;另一个与STL不同的是,boost某些库需要编译成相应的静态库与动态库才可以用。[2] Boost Graph Library(boost 图形库,一套用于图形的容器与算法组件)[3] 其实普通数组的指针也是可以看作为一种简单的iterator

Boost入门

时间: 2024-07-29 15:02:24

Boost入门的相关文章

Linux上安装使用boost入门指导

Data Mining Linux上安装使用boost入门指导 获得boost boost分布 只需要头文件的库 使用boost建立一个简单的程序 准备使用boost二进制文件库 把你的程序链接到boost库 1.获得boost 下载boost_1_46_1.tar.bz2 解压 2.boost分布 boost_1_46_1.........................boost根目录 boost/.....................................所有boost头文件

boost——入门指南

什么是boost boost库是一个开源免费的第三方库,它是一个非常优秀的库,是C++标准的最好实践之一,因此也经常被用于商业的开发.所以,如果你是搞C++的,还没有听过或用过boost,你就out了,想想自己是不是跟不上技术的步伐了,哈哈-- 关于boost的地位,大家可以看看其官方文档: We aim to establish "existing practice" and provide reference implementations so that Boost librar

c++ boost库

boost是C++标准委员会库工作组发起的开源库,内容十分强大.支持正则表达式,多线程编程,数据结构图(STL扩展),智能指针,python语法等功能. linux下安装boost http://blog.csdn.net/i_noname/article/details/632344 Linux上安装使用boost入门指导 http://www.cnblogs.com/zhangchaoyang/articles/2048952.html 走进Boost [Boost 使用入门] http:/

vs 2005 使用 boost regex

第一步: Boost 入门及其VS2005下编译boost库 boost.regex库安装指南 Boost下载和Boost安装去哪下载Boost呢?英文http://www.boost.org ,中文http://boost.c-view.org,可以找到一个.zip或.tar.gz格式的压缩包.下载完毕后,解压到某个目录,比如boost_1_26_0,里面一般有这么几个子目录:boost.libs.more.people.status.tools,看看没问题就行了.如果Boost更新时您懒得去

boost.python入门教程 ----python 嵌入c++

boost.python 中 python 嵌入c++ 部分,网上找到的中文资料似乎都有些过时了, 如 boost.python学习笔记 http://edyfox.codecarver.org/html/boost_python.html 在boost.python版本2中,提供更加简洁易用的接口,我们可以使用从而 代替原始的PyRun_SimpleString等等python c 转换api. 关于python与C++混合编程,事实上有两个部分 extending   所谓python 程序

Boost.Asio入门(CSDN也有Markdown了,好开森)

Boost.Asio入门 首先,让我们先来了解一下什么是 Boost.Asio?怎么编译它?了解的过程中我们会给出一些例子.然后在发现 Boost.Asio 不仅仅是一个网络库的同时你也会接触到 Boost.Asio 中最核心的类--io_service. 什么是Boost.Asio 简单来说,Boost.Asio是一个跨平台的.主要用于网络和其他一些底层输入/输出编程的 C++ 库. 网络 API 的设计方式有很多种,但是 Boost.Asio 的的方式远远优于其它的设计方式.它在 2005

boost::filesystem库使用入门

以下知识点转自:点击打开原文链接 今天拿起手要用C++写个小工具,从指定的目录递归遍历文件,然后做一下处理.又翻了一下boost的filesystem库.小结一下,希望能加深印象,免得下次又要查看文档. 1. path对象就是一个跨平台的路径对象.有许多方法访问路径的各个部分,也用它的iterator迭代路径中的各个部分: path构造目录结构的时候使用"/"运算符,非常直观. 比如path p1; path p2 = p1/"something"; p1 /= &

Boost::Asio入门剖析

Boost::Asio可以在socket等I/O对象上执行同步或异步操作,使用Boost::Asio前很有必要了解Boost::Asio.你的程序以及它们交互的过程. 作为一个引导的例子,我们思考一个当一个socket执行连接操作时发生了什么,我们首先开始一个同步的例子 你的程序需要一个io_service对象,io_service把你的程序和操作系统I/O设备链接起来. boost::asio::io_service io_service; 你的程序需要一个I/O对象来执行I/O操作,比如tc

Boost库学习之旅入门篇

学习及使用Boost库已经有一段时间了,Boost为我的日常开发中带来了极大的方便,也使得我越来越依赖于boost库了.但boost功能太多,每次使用还是得翻看以前的 资料,所以为了以后可以更方便的使用,在此对常用的功能作一个总结,也希望以此与大家共勉. boost库下载,Svn地址: http://svn.boost.org/svn/boost/trunk 编译源码 编译boost库自带脚本解释工具: 使用vs自带命令行工具Visual Studio 命令提示(2010),运行bat脚本boo