boost 基础

Boost介绍和安装

Boost是一套开放源代码、高度可移植的C++库。boost按功能分为:字符串、容器、算法、迭代器、数据结构、内存管理、多线程、IO等。

Windows下安装:

  1. 下载地址:http://www.boost.org,下载最新zip文件
  2. 把源码解压到某个地方,比如C:\program files\boost
  3. 从命令行模式进入到根目录,编译生成lib文件
    1. 进入到C:\Program Files\boost\boost_1_51_0,先后输入两个命令:
    2. .\bootstrap.bat
    3. .\b2.exe
  4. 设置IDE的环境变量
    1. 如果是用visual studio进行开发,对include添加一条路径,C:\Program Files\boost\boost_1_51_0
    2. 对lib添加一条路径,C:\Program Files\boost\boost_1_51_0\stage\lib
  5. 到此为止,环境变量都设置好了可以进行开发了。
Boost组件介绍
String and text processing

    提供了字符串的操作功能,大概分为五个组件。但要注意的是,某些组件效率上可能会有问题,比如字符串与基本类型的相互转换、格式化等,它们的实现是先把输入参数转化为STL的字符流,然后通过字符流转换为用户想要的类型输出(从这一点也可以看出,可以相互转换的类型只限于字符流可接受的那几类,字符流使用与可接受类型与io流基本一样)。

组件 描述
lexical_cast 字符串与其它类型的相互转换
format 格式化字符
regex 正则表达式
spirit 字符串分析框架。用inline的C++写成的EBNF语法。
tokenizer 按位移或字符提取字符串

lexical_cast

lexical_cast实现了C语言中itoa,atoi等函数的功能。lexical_cast就是对stringstream的一个封装,用一个stringstream做中介,实现转换。(浮点数精度默认为6位) 举例:

#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"); 
}
注意:输入数据必须“完整”地转换,否则抛出bad_lexical_cast异常。

format

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

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>>
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/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的好,但并非不可以代替。
组件 描述
pool 内存池管理
smart_ptr 智能指针,总共提供了6种类型
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入门
  2. Boost的安装
  3. Boost入门向导

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值