一、 Boost入门 2 二、 Boost::array: 4 1、 范例: 4 三、 Boost::bind 4 1、 范例: 4 四、 Boost::function 5 1、 范例: 5 五、 Boost::ref 和 boost::cref 7 1、 介绍: 7 2、 范例: 7 六、 C++ RAII 资源获取即初始化 8 1、 简介: 8 2、 特点: 8 3、 范例: 9 七、 Std::auto_ptr ——智能指针 9 1、 介绍: 9 2、 范例: 10 八、 Boost::scoped_ptr作用域指针 11 1、 简介: 11 2、 范例: 11 九、 Boost::thread 14 1、 范例: 14 十、 Boost::unordered 15 1、 范例: 15 十一、 Boost::regex 正则 16 1、 简介: 16 2、 特殊字符介绍 16 3、 类的特性模板参数(the traits template parameter)。 16 4、 范例: 23
①.boost是一个准标准库,相当于STL的延续和扩充,它的设计理念和STL比较接近,都是利用泛型让复用达到最大化。不过对比STL,boost更加实用。STL集中在算法部分,而boost包含了不少工具类,可以完成比较具体的工作。 ②.boost主要包含一下几个大类:字符串及文本处理、容器、迭代子(Iterator)、算法、函数对象和高阶编程、泛型编程、模板元编程、预处理元编程、并发编程、数学相关、纠错和测试、数据结构、输入/输出、跨语言支持、内存相关、语法分析、杂项。 有一些库是跨类别包含的,就是既属于这个类别又属于那个类别。 ③.在文本处理部分,conversion/lexcial_cast类用于“用C++”的方法实现数字类型和字符串之间的转换。 主要是替代C标准库中的 atoi、 itoa之类的函数。当然其中一个最大的好处就是支持泛型了。 ④.format库提供了对流的“printf-like”功能。printf里使用%d、%s等等的参数做替换的方法在很多情况下还是非常方便的,STL的iostream则缺乏这样的功能。format为stream增加了这个功能,并且功能比原始的printf更强。 ⑤.regex,这个不多说了,正则表达式库。如果需要做字符串分析的人就会理解正则表达式有多么有用了。 ⑥.spirit,这个是做LL分析的框架,可以根据EBNF规则对文件进行分析。(不要告诉我不知道什么是EBNF)。做编译器的可能会用到。一般人不太用的到。 ⑦.tokenizer库。我以前经常在上看到有人问怎么把一个字符串按逗号分割成字符串数组。也许有些人很羡慕VB的split函数。现在,boost的tokenizer也有相同的功能了,如果我没记错的话,这个tokenizer还支持正则表达式,是不是很爽? ⑧.array: 提供了常量大小的数组的一个包装,喜欢用数组但是苦恼数组定位、确定数组大小等功能的人这下开心了。 ⑨.dynamic_bitset,动态分配大小的bitset,我们知道STL里有个bitset,为位运算提供了不少方便。可惜它的大小需要在编译期指定。现在好了,运行期动态分配大小的bitset来了。 ⑩.graph。提供了图的容器和相关算法。我还没有在程序中用到过图,需要用的人可以看看。 ⑪.multi_array提供了对多维数组的封装,应该还是比较有用的。 ⑫.并发编程里只有一个库,thread,提供了一个可移植的线程库,不过在Windows平台上我感觉用处不大。因为它是基于Posix线程的,在Windows里对Posix的支持不是很好。 ⑬.接下来的 数学和数值 类里,包含了很多数值处理方面的类库,数学类我也不太熟,不过这里有几个类还是很有用的,比如rational分数类,random随机数类,等等。 ⑭.static_assert,提供了编译器的assert功能。 ⑮.test库,一个单元测试框架,非常不错。 ⑯.concept_check提供了泛型编程时,对泛型量的一点检查,不是很完善,不过比没有好。 ⑰.数据类型类any,一个安全的可以包含不同对象的类。把它作为容器的元素类型,那么这个容器就可以包含不同类型的元素。比用void *要安全。 ⑱.compressed_pair,跟STL里的pair差不多。不过对空元素做了优化。 ⑲.tuple,呵呵,也许是某些人梦寐以求的东西。可以让函数返回多个值。 ⑳.跨语言支持:Python,呵呵,好东东啊,可以将C++的类和函数映射给python使用。以下为几个上的关于boost.python的中文资料:http://dev.csdn.NET/article/19/19828.shtm,http://dev.csdn.net/article/19/19829.shtm,http://dev.csdn.net/article/19/19830.shtm,http://dev.csdn.net/article/19/19831.shtm 21.pool:内存池,呵呵,不用害怕频繁分配释放内存导致内存碎片,也不用自己辛辛苦苦自己实现了。 22.smart_ptr:智能指针,这下不用担心内存泄漏的问题了吧。不过,C++里的智能指针都还不是十全十美的,用的时候小心点了,不要做太技巧性的操作了。 23.date_time,这个是平台、类库无关的实现,如果程序需要跨平台,可以考虑用这个。 24.timer,提供了一个计时器,虽然不是Windows里那种基于消息的计时器,不过据说可以用来测量语句执行时间。 25.uitlity里提供了一个noncopyable类,可以实现“无法复制”的类。很多情况下,我们需要避免一个类被复制,比如代表文件句柄的类,文件句柄如果被两个实例共享,操作上会有很多问题,而且语义上也说不过去。一般的避免实例复制的方法是把拷贝构造和operator=私有化,现在只要继承一下这个类就可以了,清晰了很多。 26.value_initialized:数值初始化,可以保证声明的对象都被明确的初始化,不过这个真的实用吗?似乎写这个比直接写初始化还累。呵呵,仁者见仁了。 27.这里面除了regex、python和test需要编译出库才能用,其他的大部分都可以直接源代码应用,比较方便。其实这些库使用都不难。最主要的原因是有些库的使用需要有相关的背景知识,比如元编程、STL、泛型编程等等。
1、范例:
#include<boost/array.hpp> #include <iostream> #include <string> using namespace std; using namespace boost; void mainA () { Boost::array <int, 5> barray = { 1, 2, 3, 4, 5 }; barray[0] = 10; barray.at(4) = 20; int *p = barray.data();//存储数组的指针 for (int i = 0; i < barray.size();i++) { cout << barray[i] << " " << p[i] << endl; } array<string, 3> cmd = { "calc", "notepad", "tasklist" }; cin.get(); }1、范例:
#include <iostream> #include <string> #include <boost/bind.hpp> #include <vector> #include <algorithm> #include <functional> using namespace std; using namespace boost; //绑定函数的默认值,继承二进制函数类的所有类容 class add:public std::binary_function<int ,int,void> { public: void operator()(int i,int j) const { std::cout << i + j << endl; } }; void add(int i, int j) { std::cout << i + j << endl; } void mainB() { vector<int> myv; myv.push_back(11); myv.push_back(23); myv.push_back(34); //for_each(myv.begin(), myv.end(), bind1st(add(),10)); for_each(myv.begin(), myv.end(), boost::bind(add, 13, _1)); //bind设置默认参数调用,函数副本机制,不能拷贝构造 cin.get(); }1、范例:
#include <iostream> #include <string> #include <boost/bind.hpp> #include <boost/function.hpp> #include <vector> #include <algorithm> #include <functional> #include <stdlib.h> using namespace std; using namespace boost; void mainC() { //atoi //char * to int //boost::function<int(char *)> fun = atoi; cout << fun("123") + fun("234") << endl; fun = strlen; cout << fun("123") + fun("234") << endl; cin.get(); } void mainD() { boost::function<int(char *)> fun = atoi; cout << fun("123") + fun("234") << endl; fun = boost::bind(strcmp, "ABC", _1); cout << fun("123") << endl; cout << fun("ABC") << endl; cin.get(); } /*在一个类中调用另外一个类中的函数,*/ class manager { public: void allstart() { for (int i = 0; i < 10;i++) { if (workid) { workid(i); } } } void setcallback(boost::function<void(int)> newid)//绑定调用 { workid = newid; } public: boost::function<void(int)> workid; }; class worker :public std::binary_function<int, int, void> { public: void run(int toid) { id = toid; cout << id << "工作" << endl; } void operator ()(int toid,int num)const { cout << toid + num << "工作" << endl; } public: int id; }; void add1(int i, int j) { std::cout << i + j << endl; } void main() { manager m; worker w; vector<int> myv; myv.push_back(11); myv.push_back(23); myv.push_back(34); for_each(myv.begin(), myv.end(), bind(add1, 113, _1)); //类的成员函数需要对象来调用,绑定了一个默认的对象 m.setcallback(boost::bind(&worker::run, &w, _1)); m.allstart(); //m.setcallback(boost::bind(worker(),113,_1)); //m.allstart(); //for_each(myv.begin(), myv.end(), bind(&worker::run, &w, 113, _1)); for_each(myv.begin(), myv.end(), boost::bind(worker(), 113, _1)); cin.get(); }1、介绍: ①.库ref在boost/ref.hpp中提供了模板工厂函boost::ref,boost::cref分别对应包装引用和常引用。 ②.当在某些情况下需要拷贝对象参数,如果该对象无法进行拷贝,或者拷贝代价过高,这时候就可以选择ref。 2、范例:
#include <iostream> #include <string> #include <boost/bind.hpp> #include <boost/function.hpp> #include <vector> #include <algorithm> #include <functional> #include <stdlib.h> using namespace std; using namespace boost; void print(std::ostream &os,int i) { os << i << endl; } void mainF() { //不可以拷贝的对象可以用ref boost::function<void(int)> pt = boost::bind(print,boost::ref(cout), _1); vector<int > v; v.push_back(11); v.push_back(12); v.push_back(13); for_each(v.begin(), v.end(), pt); std::cin.get(); }1、简介: ①.RAII是resource acquisition is initialization的缩写,意为“资源获取即初始化”。它是C++之父Bjarne Stroustrup提出的设计理念,其核心是把资源和对象的生命周期绑定,对象创建获取资源,对象销毁释放资源。在RAII的指导下,C++把底层的资源管理问题提升到了对象生命周期管理的更高层次。 ②.说起来,RAII的含义倒也不算复杂。用白话说就是:在类的构造函数中分配资源,在析构函数中释放资源。这样,当一个对象创建的时候,构造函数会自动地被调用;而当这个对象被释放的时候,析构函数也会被自动调用。于是乎,一个对象的生命期结束后将会不再占用资源,资源的使用是安全可靠的。 2、特点: ①.C++ RAII体现出了简洁、安全、实时的特点: ②.1.概念简洁性:让资源(包括内存和非内存资源)和对象的生命周期绑定,资源类的设计者只需用在类定义内部处理资源问题,提高了程序的可维护性; ③.2.类型安全性:通过资源代理对象包装资源(指针变量),并利用运算符重载提供指针运算方便使用,但对外暴露类型安全的接口; ④.3.异常安全性:栈语义保证对象析构函数的调用,提高了程序的健壮性; ⑤.4.释放实时性:和GC相比,RAII达到了和手动释放资源一样的实时性,因此可以承担底层开发的重任。 3、范例:
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <stdlib.h> #include <string> using namespace std; class mystr { public: char *p = nullptr; public: mystr(const char *str) { int length = strlen(str); p = new char[length + 1]; strcpy(p, str); p[length] = '\0'; } ~mystr() { cout << "销毁" << endl; delete[] p; } }; void go() { char *p = new char[100]; mystr str1 = "ABCD";//RAII避免内存泄漏,一般情况下,堆上的内存当作栈上来使用 //栈内存有限,希望自动释放,用很大的内存。 } void mainHG() { go(); cin.get(); }1、介绍: ①.智能指针就是RAII中相当典型的一例,它很好的体现了RAII的理念,自动获取释放; 2、范例:
#include <iostream> #include <string> #include <vector> #include <algorithm> #include <functional> #include <stdlib.h> using namespace std; template<class T> class pmy { public: pmy() { } pmy(T *t) { p = t; } ~pmy() { if (p!=nullptr) { delete p ; P = nullptr ; } } T operator *() { return *p; } private: T *p=nullptr; }; class Test { public: Test() { cout << "Test create" << endl; } ~Test() { cout << "Test delete" << endl; } }; void run() { pmy<Test> p(new Test);//智能指针,智能释放 } void mainH() { run(); cin.get(); }1、简介: ①.相同点:两者都是智能指针,自动释放内存。机理都是重载了*,->运算符,代理指针功能。在构造和系析构中自动创建和释放资源; ②.不同点:std::auto_ptr 所有权可以转让, 而boost::scoped_ptr所有权不可以转让; ③.std::auto_ptr 实现原理比boost::scoped_ptr简单,在所有权不用转让的情况下,优先考虑boost::scoped_ptr ; 2、范例:
#include <iostream> #include <vector> #include<algorithm> #include <boost/scoped_ptr.hpp> #include <boost/scoped_array.hpp> #include <boost/shared_ptr.hpp> #include <boost/shared_array.hpp> #include<boost/weak_ptr.hpp> #include <windows.h> using namespace std; void mainI() { boost::scoped_ptr<int> p(new int);//自动释放内存 *p = 12; cout << *p.get() << endl; //获取指针指向的内容 p.reset(new int);//指针自动释放 *p.get() = 3; boost::scoped_ptr<int> pA(nullptr); //独占内存,不能将内存共享给其他人 //pA = p; cout << *p.get() << endl; cin.get(); } /*boost::scoped_array作用域数组,独享内存,自动释放内存*/ void mainG() { boost::scoped_array<int> p(new int[10]);//自动释放内存 //boost::scoped_array<int> pA(p);不行,因为独享指针 *p.get() = 1; p[3] = 2; p.reset(new int[5]);//只能指针 cin.get(); } /*boost::shared_ptr共享指针*/ void show(boost::shared_ptr<int> p) { cout << *p << endl; } void mainK() { vector<boost::shared_ptr<int> > v; boost::shared_ptr<int> p1(new int(11)); boost::shared_ptr<int> p2(new int(12)); boost::shared_ptr<int> p3(p2);//拷贝 v.push_back(p1); v.push_back(p2); v.push_back(p3); for_each(v.begin(), v.end(), show); cin.get(); } /*共享指针在类中的作用*/ class runclass { public: int i = 0; public: runclass(int num) :i(num) { cout << "i create" <<i<< endl; } runclass() { cout << "i create" << i << endl; } ~runclass() { cout << "i delete" <<i<< endl; } void print() { cout << "i =" << i<<endl; } }; void testfun() { boost::shared_ptr<runclass> p1(new runclass(10)); boost::shared_ptr<runclass> p2(p1); boost::shared_ptr<runclass> p3(p1); p1.reset(new runclass(12)); p1->print(); //12 p2->print(); //10 p3->print(); //10 } /*boost::shared_array共享指针数组*/ void testfunarray() { boost::shared_array<runclass> p1(new runclass[5]); boost::shared_array<runclass> p2(p1); } void mainL() { //testfun(); testfunarray(); cin.get(); } /*弱指针*/ DWORD WINAPI reset(LPVOID p) { boost::shared_ptr<int > *sh = static_cast<boost::shared_ptr<int> *> (p); sh->reset();//指针的重置,释放内存 std::cout << "指针执行释放" << endl; return 0; } DWORD WINAPI print(LPVOID p) { boost::weak_ptr<int > * pw = static_cast<boost::weak_ptr<int > *>(p); boost::shared_ptr<int > sh = pw->lock();//锁定不可以释放 Sleep(5000); if (sh) { std::cout << *sh << endl; } else { std::cout << "指针已经被释放" << endl; } return 0; } void main123() { boost::shared_ptr<int> sh(new int(99)); boost::weak_ptr<int > pw(sh); HANDLE threads[2]; threads[0] = CreateThread(0, 0, reset, &sh, 0, 0);//创建一个线程 threads[1] = CreateThread(0, 0, print, &pw, 0, 0); Sleep(1000); WaitForMultipleObjects(2, threads, TRUE, INFINITE);//等待线程结束 cin.get(); }1、范例:
#include <iostream> #include <vector> #include<algorithm> #include<boost/thread.hpp> #include <windows.h> using namespace std; using namespace boost; void wait(int sec) { boost::this_thread::sleep(boost::posix_time::seconds(sec)); } void threadA() { for (int i = 0; i < 10;i++) { wait(1); std::cout << i << endl; } } void threadB() { try { for (int i = 0; i < 10; i++) { wait(1); std::cout << i << endl; } } catch (boost::thread_interrupted &) { } } void mainO() { boost::thread t(threadA ); //boost::thread t(threadB ); wait(3); t.interrupt();//结束线程 t.join(); cin.get(); }1、范例:
#include <iostream> #include<boost/unordered_set.hpp> #include<string> using namespace std; void mainAAAC() { boost::unordered_set<std::string> myhashset; myhashset.insert("ABC"); myhashset.insert("ABCA"); myhashset.insert("ABCAG"); for (auto ib = myhashset.begin(); ib != myhashset.end();ib++) { cout << *ib << endl; } std::cout << (myhashset.find("ABCA1") != myhashset.end()) << endl; cin.get(); }4、范例:
#include <boost/regex.hpp> #include <locale> #include <iostream> #include <string> using namespace std; void mainA123() { std::locale::global(std::locale("English")); string str = "chinaen8Glish"; boost::regex expr("\\w+\\d\\u\\w+");//d代表数字, //匹配就是1,不匹配就是0 cout << boost::regex_match(str, expr) << endl; cin.get(); } void mainB123() { std::locale::global(std::locale("English")); string str = "chinaen8Glish9abv"; boost::regex expr("(\\w+)\\d(\\w+)");//d代表数字, boost::smatch what; if (boost::regex_search(str,what,expr))//按照表达式检索 { cout << what[0] << endl; cout << what[1] << endl; } else { cout << "检索失败"; } cin.get(); } void mainC1234() { string str = "chinaen8 Glish9abv"; boost::regex expr("\\d");//d代表数字, string kongge = "______"; std::cout << boost::regex_replace(str, expr, kongge) << endl; cin.get(); }