1. 程式人生 > >Boost程式庫入門學習

Boost程式庫入門學習

優秀的程式設計師要能夠知其所以然,而不是重複的造輪子,近期目標是學習優秀的第三方庫,同時嘗試使用C++11/14新特性,然後吸取精華用到專案中去,加油~

參考書籍:
羅劍鋒寫的《Boost程式庫完全開發指南》和《Boost程式庫探祕》,前者是一個大體的介紹,後者是針對一些諸如模板超程式設計等高階特性做了深入的探討。

一、Boost庫概述

Boost是一個功能強大、構造精巧、跨平臺、開源並且完全免費的C++程式庫。
C++11標準庫中有三分之二來自Boost庫,Boost庫建立在“既有的實踐”之上並提供參考實現,大大增強了C++的功能和表現力。

下載地址:

https://sourceforge.net/projects/boost/files/boost/1.63.0/

安裝:

tar -xzvf boost_1_63_0.tar.gz
cd boost_1_63_0
//編譯前配置工作
./bootstrap.sh --prefix=/usr/local
//命令b2開始真正的編譯並安裝boost
./b2 install --with=all

我們可以看到:標頭檔案安裝到了/usr/local/include,庫檔案安裝到/usr/local/lib中。

Boost庫大多陣列件不需要編譯連結,在自己的原始碼中直接包含標頭檔案即可。如果要使用boost::tribool,只需要在C++原始檔中新增如下include語句:

#include <boost/logic/tribool.hpp>
using namespace boost; //名稱空間

檔案字尾.hpp = .h + .cpp,把C++類的宣告和實現放在了一個檔案中。

剩下的少量庫(如thread,date_time)必須編譯成靜態庫或者動態庫,並在構建時指定連結選項。

補充

這裡補充一下Windows環境下如何安裝,我們假定原始碼資料夾放在桌面,資料夾名字為code,我們需要在visual studio的工程中設定編譯器搜尋路徑為:
在這裡插入圖片描述

二、Boost開發環境驗證

1) 不使用編譯庫

編寫一個簡單的Boost應用程式來驗證開發環境。

#include <boost/version.hpp>
#include <boost/config.hpp>
#include <iostream>
using namespace std;

int main()
{

    cout<< BOOST_VERSION<<endl; //版本號
    cout<< BOOST_LIB_VERSION<<endl;

    cout<< BOOST_PLATFORM<<endl; //作業系統
    cout<< BOOST_COMPILER<<endl;
    cout<< BOOST_STDLIB<<endl;

}

編譯

g++ test.cpp -o test
./test

輸出

106300
1_63
linux
GNU C++ version 5.4.0 20160609
GNU libstdc++ version 20160609
2) 使用編譯庫

下面程式碼是執行緒的helloworld和timer類的使用例子。

#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/timer.hpp>

using namespace std;
using namespace boost;

void hello()
{
    cout<<"hello boost"<<endl;
}

int main()
{
    timer t;
    boost::thread thrd(&hello);
    thrd.join();

    cout<<t.elapsed_max()/3600<<endl;//最大時間,單位:小時
    cout<<t.elapsed_min()<<endl; //最小統計時間,單位:秒
    cout<<t.elapsed()<<endl;//從建立物件開始,時間流失統計


    return 0;
}

由於使用了thread庫,我們需要在連結時指定路徑,然後測試:

g++ hello.cpp -o hello -I/usr/local/include  -L/usr/local/lib -lboosstem -lboost_thread

其中編譯指令選項參考之前文章編譯與連結複習,這裡需要說明的是,執行後可能出現錯誤:
在這裡插入圖片描述

我們首先檢視可執行檔案的所連結的檔案,然後查詢/usr路徑下是否有該檔案,若有說明連結設定不當,這是因為程式執行時,會在.usr/lib和/lib等目錄中查詢需要的動態庫檔案。若找到則載入動態庫檔案,否則提示類似上述錯誤。

//方法一:
LD_LIBRARY_PATH="/usr/local/lib" ./hello

//方法二:
 export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
 sudo ldconfig

之後,執行沒有錯誤,輸出:

hello boost
2.56205e+09
1e-06
0.000381
3) progress_timer學習

progress_timer也是一個計時器,繼承自timer,會在析構時自動輸出時間,省去了timer手動呼叫elapsed()的工作。

#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/timer.hpp>
#include <boost/progress.hpp>
using namespace std;
using namespace boost;

int main()
{  
	//測試progress_timer
    progress_timer pt;

    return 0;
}

這樣,程式退出main函式作用域導致pt析構時,會自動輸出流逝的時間。

缺點:精度不夠,Linux下單位為s。

三、Boost元件progress_display

progress_display是一個獨立的類,與timer庫中其它的兩個元件-timer和progress_timer沒有任何關係。

#include <iostream>
#include <boost/progress.hpp>
#include <vector>
#include <fstream>
using namespace std;
using namespace boost;
 

int main()
{
    vector<string> vec(1000);
	ofstream  fs("./test.txt");  //一個字串向量
    
	//宣告一個progress_display物件,基數是vec的大小
	progress_display pd(vec.size());

	//迭代遍歷
	for(auto& x:vec)
	{
		fs<< x<< endl;  //更新進度
		++pd;
	}
    return 0;
}

我們把一些儲存在std::vector中的字串以每個一行的形式寫入到文字檔案,由於字串數量很多,可能操作會耗費很多時間。progress能讓程式有一個友好的人機介面,讓使用者知道程式的進度。

缺陷:無法把進度顯示輸出與程式的輸出分離。

三、date_time庫概述

date_time類,可以滿足絕大多數程式對時間的要求,但是不能處理1400年以前的時間,但是它的優點是很明顯的,它允許我們更加自由地去操縱時間。