Boost常用库介绍

Boost常用库介绍

关于Boost库怎样安装,我这里不多讲,网上资料很多。我这里重点介绍一下boost的几个库,以便在我们以后的开发中提高工作效率。Boost库文件采用的.hpp的后缀,而不是分成两个文件,也就是”.h+.cpp”,之所以这样做是有理由的,首先就是与普通的C/C++头文件区分,另外一个原因就是使Boost库不需要预先编译,直接引用程序员的工程即可编译链接,方便了库的使用。最后一个(无奈的)原因就是C++编译器的限制,许多编译器尚不支持C++标准提出的模板的分离编译模式,而Boost使用了大量的模板。Boost中90%的库不需要编译,但像data_time、regex、test、thread等库必须编译成静态库或者动态库。好了,言归正传,下面我们来开始学习boost库吧。

日期和时间处理:
timer:包含三个主件,分别是:计时器类timer、progress_timer和进度条指示类progress_display。源码比较简单,我们可以借鉴源码处理时间和进度条。在linux操作系统中timer最大只能计时0.596523h(我们可以改写源码,扩大计时时间),但是可以精确到微秒。我们在计时,进度显示中可能会用到,下面我们给一个progress_display库的使用示例。

#include <boost/progress.hpp>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>

int main()
{
std::vector<std::string> v(100);
std::ofstream fs("test");
boost::progress_display pd(v.size());
std::vector<std::string>::iterator pos;
for(pos=v.begin();pos!=v.end();++pos)
{
fs<<*pos<<std::endl;
++pd;
sleep(1);
}
}


输出结果:
0% 10 20 30 40 50 60 70 80 90 100%
|----|----|----|----|----|----|----|----|----|----|
*****
上例中实现了将一个容器的内容拷贝到一个文件中的进度条显示的过程。
DateTime:提供了扩展来处理时区的问题,且支持历法日期和时间的格式化输入与输出。Boost.DateTime 只支持基于格里历的历法日期,这通常不成问题,因为这是最广泛使用的历法。 如果你与其它国家的某人有个会议,时间在2010年1月5日,你可以期望无需与对方确认这个日期是否基于格里历。
格里历是教皇 Gregory XIII 在1582年颁发的。 严格来说,Boost.DateTime 支持由1400年至9999年的历法日期,这意味着它支持1582年以前的日期。 因此,Boost.DateTime 可用于任一历法日期,只要该日期在转换为格里历后是在1400年之后。 如果需要更早的年份,就必须使用其它库来代替。
用于处理历法日期的类和函数位于名字空间 boost::gregorian 中,定义于 boost/date_time/gregorian/gregorian.hpp。 要创建一个日期,请使用 boost::gregorian::date 类。

#include <boost/date_time/gregorian/gregorian.hpp> 
#include <iostream> 
int main() 
{ 
boost::gregorian::date d(2010, 1, 30); 
std::cout << d.year() << std::endl; 
std::cout << d.month() << std::endl; 
std::cout << d.day() << std::endl; 
std::cout << d.day_of_week() << std::endl; 
std::cout << d.end_of_month() << std::endl; 
}


输出结果:
2010
Jan
30
Sat
2010-Jan-31


智能指针:
shared_ptr:是一个最像指针的“智能指针”,它实现了引用计数型的智能指针,可以自由的拷贝和赋值,在任意的地方共享它,当没有代码使用它是才删除被包装的动态分配的对象。shared_ptr也可以安全的放在标准容器中,可以像使用指针以用使用shared_ptr。性能和使用指针相差无几,却能有效的防止内存泄露。

#include <boost/shared_ptr.hpp>
#include <iostream>
#include <vector>
class Shared
{
public:
Shared()
{
std::cout << "ctor() called"<<std::endl;
}
Shared(const Shared & other)
{
std::cout << "copy ctor() called"<<std::endl;
}
~Shared()
{
std::cout << "dtor() called"<<std::endl;
}
Shared & operator = (const Shared & other)
{
std::cout << "operator = called"<<std::endl;
}
};
int main()
{
typedef boost::shared_ptr<Shared> SharedSP;
typedef std::vector<SharedSP> VShared;
VShared v;
v.push_back(SharedSP(new Shared()));
v.push_back(SharedSP(new Shared()));
}

字符串处理和格式化输出:
lexical_cast:lexical_cast库进行“字面量”转换,类似C中的atoi函数,可以进行字符串、整数/浮点数之间的字面转换。

#include <boost/lexical_cast.hpp> 
void test_lexical_cast() 
{ 
int i = boost::lexical_cast<int>("123"); 
cout << i << endl; 
} 


format:用于替代C里面的sprintf,优点是类型安全,不会因为类型和参数不匹配而导致程序崩溃,而且还可以重复使用参数。

#include <boost/format.hpp> 
void test_format() 
{ 
cout << 
boost::format("writing %1%, x=%2% : %3%-th try") 
% "toto" 
% 40.23 
% 50 
<<endl; 
format f("a=%1%,b=%2%,c=%3%,a=%1%"); 
f % "string" % 2 % 10.0; 
cout << f.str() << endl; 
} 


string_algo:它是一个非常全面的字符串算法库,提供了大量的字符串操作函数,如大小写无关比较、修剪、特定模式的字串查找等,可以在不使用正则表达式的情况下处理大多数字符串相关问题。

#include <boost/algorithm/string.hpp>
Using namespace boost;
int main()
{
string str(“readme.txt”);
if(ends_with(str,”txt”))
{
cout<<to_upper_copy(str)+”UPPER”<<endl;
assert(ends_with(str,”txt”));
}
replace_first(str,”readme”,”followme”);
cout<<str<<endl;
vector<char> v(str.begin(),str.end());
vector<char> v2=to_upper_copy(erase_first_copy(v,”txt”));
for(int i=0;i<v2.size();++i)
{
cout<<v2[i];
}
}


tokenizer:tokenizer库是一个专门用于分词的字符串处理库,可以用简单易用的方法把一个字符串分解成若干个单词。它与string_algo库的分割算法很类似,但是有更多的变化。

#include <boost/tokenizer.hpp> 
void test_tokenizer() 
{ 
string s("This is , a ,test!"); 
boost::tokenizer<> tok(s); 
for(tokenizer<>::iterator beg=tok.begin(); beg!=tok.end();++beg) 
{ 
cout << *beg << " "; 
} 
} 


Xpressive:是一个先进的、灵活的、功能强大的正则表达式库,提供了对正则表达式的全面支持,而且比原来的正则表达式库boost.regex要好的是不需要编译。

#include <boost/xpressive/xpressive_dynamic.hpp>
int main()
{
cregex reg=cregex::compile(“a.c”);
assert(regex_match(“abc”,reg));
assert(regex_match(“a+c”,reg));
assert(!regex_match(“ac”,reg));
assert(!regex_match(“abd”,reg));
}


容器:
any:是一种通用的数据类型,可以将类型包装后统一放在容器中,最重要的是它是类型安全的。使用方法: any::type() 返回包装的类型 any_cast可用于any到其他类型的转化

#include <boost/any.hpp> 
void test_any() 
{ 
typedef std::vector<boost::any> many; 
many a; 
a.push_back(2); 
a.push_back(string("test")); 
for(unsigned int i=0;i<a.size();++i) 
{ 
cout<<a[i].type().name()<<endl; 
try 
{ 
int result = any_cast<int>(a[i]); 
cout<<result<<endl; 
} 
catch(boost::bad_any_cast & ex) 
{ 
cout<<"cast error:"<<ex.what()<<endl; 
} 
} 
} 



线程库:
boost::thread类代表一个执行线程(a thread of execution),就像std::fstream类代表一个文件一样。缺省构造函数创建一个代表当前执行线程的一个实例。重载构造函数则有一个函数对象作为参数,该函数对象没有实参(argument),也无返回值。重载的构造函数创建一个新的线程,然后调用函数对象。
由于Boost.Threads采用了函数对象,而不是函数指针,因此函数对象携带线程要用到的数据是完全可以的。这种方法更加灵活,而且类型安全。如果再和相关的函数库结合起来,比如Boost.Bind,这种方式可以让你轻松地将任意多的数据传递给新创建的线程。

#include <boost/thread/thread.hpp>
#include <iostream>
void hello()
{
std::cout << "Hello world, I'm a thread!" << std::endl;
}
int main(int argc, char* argv[])
{
boost::thread thrd(&hello);	// 译注:hello前面的&符号,可要可不要
thrd.join();

return 0;
}


不能让多个线程同时访问共享的资源是至关重要的。mutex在同一时间只能允许一个线程访问共享资源。当一个线程需要访问共享资源时,它必须先“锁住”mutex,如果任何其他线程已经锁住了mutex,那么本操作将会一直被阻塞,直到锁住了mutex的线程解锁,这就保证了共享资源,在同一时间,只有一个线程可以访问。
Boost.Threads支持两大类型的mutex:简单mutex和递归mutex。
一个线程有3种可能方法来锁定mutex:
1. 等待并试图对mutex加锁,直到没有其他线程锁定mutex;
2. 试图对mutex加锁,并立即返回,如果其他线程锁定了mutex;
3. 等待并试图对mutex加锁,直到没有其他线程锁定mutex或者直到规定的时间已过。
Boost.Threads允许你挑选最有效率的mutex。为此,Boost.Threads提供了6中类型的mutex,效率由高到低排列:boost::mutex,boost::try_mutex,boost::timed_mutex,boost::recursive_mutex,boost::recursive_try_mutex和boost::recursive_timed_mutex。

Boost.Threads提供Scoped Lock模式,防止死鎖。要构建一个这种类型的锁,需要传递一个mutex引用,构造函数将锁定mutex,析构函数将解锁mutex

boost::mutex io_mutex;
struct count
{
count(int id) : id(id) { } 
void operator()()
{
for (int i = 0; i < 10; ++i)
{
boost::mutex::scoped_lock lock(io_mutex);
std::cout << id << ": "	<< i << std::endl;
}
}
int id;
};

int main(int argc, char* argv[])
{
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
thrd1.join();
thrd2.join();

return 0;
}


下面展示了Boost.Bind库如何不写函数对象

boost::mutex io_mutex;
void count(int id)
{
for (int i = 0; i < 10; ++i)
{
boost::mutex::scoped_lock lock(io_mutex);
std::cout << id << ": " << i << std::endl;
}
}

int main(int argc, char* argv[])
{
boost::thread thrd1(boost::bind(&count, 1));	// 有无&符号均可
boost::thread thrd2(boost::bind(&count, 2));	// 有无&符号均可
thrd1.join();
thrd2.join();

return 0;
}


  • 6
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Boost是一个功能强大的C++集合,提供了许多常用的函数和模块。以下是一些常用Boost函数: 1. 字符串和文本处理Boost提供了丰富的字符串处理功能,比如lexical_cast用于数值转换,format用于字符串格式化,string_algo用于字符串算法。 2. 类型推导:Boost提供了BOOST_AUTO和BOOST_TYPEOF用于类型推导,可以方便地获取表达式的类型。 3. 智能指针:Boost提供了多种智能指针,如scoped_ptr、shared_ptr、weak_ptr等,用于管理动态分配的内存。 4. 数组和容器:Boost提供了多维数组multi_array、动态多维数组、普通数组array、散列容器unordered_set、unordered_map、双向映射容器bimap、环形缓冲区circular_buffer等,方便了数组和容器的操作和管理。 5. XML和JSON解析:Boost提供了property_tree模块,可用于解析和处理XML和JSON数据。 6. 简化循环:Boost提供了BOOST_FOREACH宏,可用于简化循环操作。 7. 随机数Boost提供了Random模块,用于生成随机数。 8. 引用Boost提供了ref模块,用于处理引用。 9. 绑定Boost提供了bind模块,用于函数对象的绑定。 10. 线程Boost提供了thread模块,用于跨平台多线程编程。 这些只是Boost的一部分常用函数,Boost还有许多其他功能和模块可供使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++ Boost:工厂函数 make_shared](https://blog.csdn.net/u014779536/article/details/116400788)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【BOOST C++BOOST C++20个分类指南](https://blog.csdn.net/gongdiwudu/article/details/127961836)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值