日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

boost C++知识点(一)

發布時間:2024/3/26 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 boost C++知识点(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 boost總覽:
Boost.Any Boost.Any 提供了一個名為 boost::any 的數據類型,可以存放任意的類型。 例如,一個類型為 boost::any 的變量可以先存放一個 int 類型的值,然后替換為一個 std::string 類型的字符串。
Boost.Array TR1 Boost.Array 可以把 C++ 數組視同 C++ 標準的容器。
Boost.Asio TR2 Boost.Asio 可用于開發異步處理數據的應用,如網絡應用。
Boost.Bimap Boost.Bimap 提供了一個名為 boost::bimap 的類,它類似于 std::map. 主要的差別在于 boost::bimap 可以同時從鍵和值進行搜索。
Boost.Bind TR1 Boost.Bind 是一種適配器,可以將函數作為模板參數,即使該函數的簽名與模板參數不兼容。
Boost.Conversion Boost.Conversion 提供了三個轉型操作符,分別執行向下轉型、交叉轉型,以及不同數字類型間的值轉換。
Boost.DateTime Boost.DateTime 可用于以靈活的格式處理、讀入和寫出日期及時間值。
Boost.Exception Boost.Exception 可以在拋出的異常中加入額外的數據,以便在 catch 處理中提供更多的信息。 這有助于更容易地調試,以及對異常情況更好地作出反應。
Boost.Filesystem TR2 Boost.Filesystem 提供了一個類來處理路徑信息,還包含了幾個訪問文件和目錄的函數。
Boost.Format Boost.Format 以一個類型安全且可擴展的 boost::format 類替代了 std::printf() 函數。
Boost.Function TR1 Boost.Function 簡化了函數指針的定義。
Boost.Interprocess Boost.Interprocess 允許多個應用通過共享內存以快速、高效的方式進行通信。
Boost.Lambda Boost.Lambda 可以定義匿名的函數。 代碼被內聯地聲明和執行,避免了單獨的函數調用。
Boost.Multiindex Boost.Multiindex 定義了一些新的容器,它們可以同時支持多個接口,如 std::vector 和 std::map 的接口。
Boost.NumericConversion Boost.NumericConversion 提供了一個轉型操作符,可以安全地在不同的數字類型間進行值轉換,不會生成上溢出或下溢出的條件。
Boost.PointerContainer Boost.PointerContainer 提供了專門為動態分配對象進行優化的容器。
Boost.Ref TR1 Boost.Ref 的適配器可以將不可復制對象的引用傳給需要復制的函數。
Boost.Regex TR1 Boost.Regex 提供了通過正則表達式進行文本搜索的函數。
Boost.Serialization 通過 Boost.Serialization,對象可以被序列化,如保存在文件中,并在以后重新導入。
Boost.Signals Boost.Signal 是一個事件處理的框架,基于所謂的 signal/slot 概念。 函數與信號相關聯并在信號被觸發時自動被調用。
Boost.SmartPoiners TR1 Boost.SmartPoiners 提供了多個智能指針,簡化了動態分配對象的管理。
Boost.Spirit Boost.Spirit 可以用類似于 EBNF (擴展巴科斯范式)的語法生成詞法分析器。
Boost.StringAlgorithms Boost.StringAlgorithms 提供了多個獨立的函數,以方便處理字符串。
Boost.System TR2 Boost.System 提供了一個處理系統相關或應用相關錯誤代碼的框架。
Boost.Thread C++0x Boost.Thread 可用于開發多線程應用。
Boost.Tokenizer Boost.Tokenizer 可以對一個字符串的各個組件進行迭代。
Boost.Tuple TR1 Boost.Tuple 提供了泛化版的 std::pair,可以將任意數量的數據組在一起。
Boost.Unordered TR1 Boost.Unordered 擴展了 C++ 標準的容器,增加了boost::unordered_set 和 boost::unordered_map.
Boost.Variant Boost.Variant 可以定義多個數據類型,類似于 union, 將多個數據類型組在一起。 Boost.Variant 比 union 優勝的地方在于它可以使用類。

2 智能指針及數組、容器
2.1 boost智能指針:
1998年修訂的第一版C++標準只提供了一種智能指針: std::auto_ptr 。 它基本上就像是個普通的指針: 通過地址來訪問一個動態分配的對象。 std::auto_ptr 之所以被看作是智能指針,是因為它會在析構的時候調用 delete 操作符來自動釋放所包含的對象。 當然這要求在初始化的時候,傳給它一個由 new 操作符返回的對象的地址。 既然 std::auto_ptr 的析構函數會調用 delete 操作符,它所包含的對象的內存會確保釋放掉。 這是智能指針的一個優點。

當和異常聯系起來時這就更加重要了:沒有 std::auto_ptr 這樣的智能指針,每一個動態分配內存的函數都需要捕捉所有可能的異常,以確保在異常傳遞給函數的調用者之前將內存釋放掉。 Boost C++ 庫 Smart Pointers 提供了許多可以用在各種場合的智能指針。

智能指針的原理基于一個常見的習語叫做 RAII :資源申請即初始化。 智能指針只是這個習語的其中一例——當然是相當重要的一例。 智能指針確保在任何情況下,動態分配的內存都能得到正確釋放,從而將開發人員從這項任務中解放了出來。 這包括程序因為異常而中斷,原本用于釋放內存的代碼被跳過的場景。 用一個動態分配的對象的地址來初始化智能指針,在析構的時候釋放內存,就確保了這一點。 因為析構函數總是會被執行的,這樣所包含的內存也將總是會被釋放。

無論何時,一定得有第二條指令來釋放之前另一條指令所分配的資源時,RAII 都是適用的。 許多的 C++ 應用程序都需要動態管理內存,因而智能指針是一種很重要的 RAII 類型。 不過 RAII 本身是適用于許多其它場景的。

#include <windows.h> class windows_handle { public: windows_handle(HANDLE h) : handle_(h) { } ~windows_handle() { CloseHandle(handle_); } HANDLE handle() const { return handle_; } private: HANDLE handle_; }; int main() { windows_handle h(OpenProcess(PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId())); SetPriorityClass(h.handle(), HIGH_PRIORITY_CLASS); }

上面的例子中定義了一個名為 windows_handle 的類,它的析構函數調用了 CloseHandle() 函數。 這是一個 Windows API 函數,因而這個程序只能在 Windows 上運行。 在 Windows 上,許多資源在使用之前都要求打開。 這暗示著一旦資源不再使用之后就應該關閉。 windows_handle 類的機制能確保這一點。

windows_handle 類的實例以一個句柄來初始化。 Windows 使用句柄來唯一的標識資源。 比如說,OpenProcess() 函數返回一個 HANDLE 類型的句柄,通過該句柄可以訪問當前系統中的進程。 在示例代碼中,訪問的是進程自己——換句話說就是應用程序本身。

我們通過這個返回的句柄提升了進程的優先級,這樣它就能從調度器那里獲得更多的 CPU 時間。 這里只是用于演示目的,并沒什么實際的效應。 重要的一點是:通過 OpenProcess() 打開的資源不需要顯示的調用 CloseHandle() 來關閉。 當然,應用程序終止時資源也會隨之關閉。 然而,在更加復雜的應用程序里, windows_handle 類確保當一個資源不再使用時就能正確的關閉。 某個資源一旦離開了它的作用域——上例中 h 的作用域在 main() 函數的末尾——它的析構函數會被自動的調用,相應的資源也就釋放掉了。

2.2 作用域指針
一個作用域指針獨占一個動態分配的對象。 對應的類名為 boost::scoped_ptr,它的定義在 boost/scoped_ptr.hpp 中。 不像 std::auto_ptr,一個作用域指針不能傳遞它所包含的對象的所有權到另一個作用域指針。 一旦用一個地址來初始化,這個動態分配的對象將在析構階段釋放。

因為一個作用域指針只是簡單保存和獨占一個內存地址,所以 boost::scoped_ptr 的實現就要比 std::auto_ptr 簡單。 在不需要所有權傳遞的時候應該優先使用 boost::scoped_ptr 。 在這些情況下,比起 std::auto_ptr 它是一個更好的選擇,因為可以避免不經意間的所有權傳遞。

#include <boost/scoped_ptr.hpp> int main() { boost::scoped_ptr<int> i(new int); *i = 1; *i.get() = 2; i.reset(new int); }

一經初始化,智能指針 boost::scoped_ptr 所包含的對象,可以通過類似于普通指針的接口來訪問。 這是因為重載了相關的操作符 operator*(),operator->() 和 operator bool() 。 此外,還有 get() 和 reset() 方法。 前者返回所含對象的地址,后者用一個新的對象來重新初始化智能指針。 在這種情況下,新創建的對象賦值之前會先自動釋放所包含的對象。

boost::scoped_ptr 的析構函數中使用 delete 操作符來釋放所包含的對象。 這對 boost::scoped_ptr 所包含的類型加上了一條重要的限制。 boost::scoped_ptr 不能用動態分配的數組來做初始化,因為這需要調用 delete[] 來釋放。 在這種情況下,可以使用下面將要介紹的 boost:scoped_array 類。

2.3. 作用域數組:
作用域數組的使用方式與作用域指針相似。 關鍵不同在于,作用域數組的析構函數使用 delete[] 操作符來釋放所包含的對象。 因為該操作符只能用于數組對象,所以作用域數組必須通過動態分配的數組來初始化。

對應的作用域數組類名為 boost::scoped_array,它的定義在 boost/scoped_array.hpp 里。

#include <boost/scoped_array.hpp> int main() { boost::scoped_array<int> i(new int[2]); *i.get() = 1; i[1] = 2; i.reset(new int[3]); }

boost:scoped_array 類重載了操作符 operator 和 operator bool()。 可以通過 operator 操作符訪問數組中特定的元素,于是 boost::scoped_array 類型對象的行為就酷似它所含的數組。

正如 boost::scoped_ptr 那樣, boost:scoped_array 也提供了 get() 和 reset() 方法,用來返回和重新初始化所含對象的地址。

2.4. 共享指針:
這是使用率最高的智能指針,但是 C++ 標準的第一版中缺少這種指針。 它已經作為技術報告1(TR 1)的一部分被添加到標準里了。 如果開發環境支持的話,可以使用 memory 中定義的 std::shared_ptr。 在 Boost C++ 庫里,這個智能指針命名為 boost::shared_ptr,定義在 boost/shared_ptr.hpp 里。

智能指針 boost::shared_ptr 基本上類似于 boost::scoped_ptr。 關鍵不同之處在于 boost::shared_ptr 不一定要獨占一個對象。 它可以和其他 boost::shared_ptr 類型的智能指針共享所有權。 在這種情況下,當引用對象的最后一個智能指針銷毀后,對象才會被釋放。

因為所有權可以在 boost::shared_ptr 之間共享,任何一個共享指針都可以被復制,這跟 boost::scoped_ptr 是不同的。 這樣就可以在標準容器里存儲智能指針了——你不能在標準容器中存儲 std::auto_ptr,因為它們在拷貝的時候傳遞了所有權。

#include <boost/shared_ptr.hpp> #include <vector> int main() { std::vector<boost::shared_ptr<int> > v; v.push_back(boost::shared_ptr<int>(new int(1))); v.push_back(boost::shared_ptr<int>(new int(2))); }

多虧了有 boost::shared_ptr,我們才能像上例中展示的那樣,在標準容器中安全的使用動態分配的對象。 因為 boost::shared_ptr 能夠共享它所含對象的所有權,所以保存在容器中的拷貝(包括容器在需要時額外創建的拷貝)都是和原件相同的。如前所述,std::auto_ptr做不到這一點,所以絕對不應該在容器中保存它們。

類似于 boost::scoped_ptr, boost::shared_ptr 類重載了以下這些操作符:operator*(),operator->() 和 operator bool()。另外還有 get() 和 reset() 函數來獲取和重新初始化所包含的對象的地址。

2.5. 共享數組:
共享數組的行為類似于共享指針。 關鍵不同在于共享數組在析構時,默認使用 delete[] 操作符來釋放所含的對象。 因為這個操作符只能用于數組對象,共享數組必須通過動態分配的數組的地址來初始化。

共享數組對應的類型是 boost::shared_array,它的定義在 boost/shared_array.hpp 里。

#include <boost/shared_array.hpp> #include <iostream> int main() { boost::shared_array<int> i1(new int[2]); boost::shared_array<int> i2(i1); i1[0] = 1; std::cout << i2[0] << std::endl; }

就像共享指針那樣,所含對象的所有權可以跟其他共享數組來共享。 這個例子中定義了2個變量 i1 和 i2,它們引用到同一個動態分配的數組。i1 通過 operator 操作符保存了一個整數1——這個整數可以被 i2 引用,比如打印到標準輸出。

和本章中所有的智能指針一樣,boost::shared_array 也同樣提供了 get() 和 reset() 方法。 另外還重載了 operator bool()。

2.6. 弱指針
到目前為止介紹的各種智能指針都能在不同的場合下獨立使用。 相反,弱指針只有在配合共享指針一起使用時才有意義。 弱指針 boost::weak_ptr 的定義在 boost/weak_ptr.hpp 里。

#include <windows.h> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> #include <iostream> DWORD WINAPI reset(LPVOID p) { boost::shared_ptr<int> *sh = static_cast<boost::shared_ptr<int>*>(p); sh->reset(); return 0; } DWORD WINAPI print(LPVOID p) { boost::weak_ptr<int> *w = static_cast<boost::weak_ptr<int>*>(p); boost::shared_ptr<int> sh = w->lock(); if (sh) std::cout << *sh << std::endl; return 0; } int main() { boost::shared_ptr<int> sh(new int(99)); boost::weak_ptr<int> w(sh); HANDLE threads[2]; threads[0] = CreateThread(0, 0, reset, &sh, 0, 0); threads[1] = CreateThread(0, 0, print, &w, 0, 0); WaitForMultipleObjects(2, threads, TRUE, INFINITE); }

boost::weak_ptr 必定總是通過 boost::shared_ptr 來初始化的。一旦初始化之后,它基本上只提供一個有用的方法: lock()。此方法返回的boost::shared_ptr 與用來初始化弱指針的共享指針共享所有權。 如果這個共享指針不含有任何對象,返回的共享指針也將是空的。

當函數需要一個由共享指針所管理的對象,而這個對象的生存期又不依賴于這個函數時,就可以使用弱指針。 只要程序中還有一個共享指針掌管著這個對象,函數就可以使用該對象。 如果共享指針復位了,就算函數里能得到一個共享指針,對象也不存在了。

上例的 main() 函數中,通過 Windows API 創建了2個線程。 于是乎,該例只能在 Windows 平臺上編譯運行。

第一個線程函數 reset() 的參數是一個共享指針的地址。 第二個線程函數 print() 的參數是一個弱指針的地址。 這個弱指針是之前通過共享指針初始化的。

一旦程序啟動之后,reset() 和 print() 就都開始執行了。 不過執行順序是不確定的。 這就導致了一個潛在的問題:reset() 線程在銷毀對象的時候print() 線程可能正在訪問它。

通過調用弱指針的 lock() 函數可以解決這個問題:如果對象存在,那么 lock() 函數返回的共享指針指向這個合法的對象。否則,返回的共享指針被設置為0,這等價于標準的null指針。

弱指針本身對于對象的生存期沒有任何影響。 lock() 返回一個共享指針,print() 函數就可以安全的訪問對象了。 這就保證了——即使另一個線程要釋放對象——由于我們有返回的共享指針,對象依然存在。

2.8. 指針容器
在你見過 Boost C++ 庫的各種智能指針之后,應該能夠編寫安全的代碼,來使用動態分配的對象和數組。多數時候,這些對象要存儲在容器里——如上所述——使用 boost::shared_ptr 和 boost::shared_array 這就相當簡單了。

#include <boost/shared_ptr.hpp> #include <vector> int main() { std::vector<boost::shared_ptr<int> > v; v.push_back(boost::shared_ptr<int>(new int(1))); v.push_back(boost::shared_ptr<int>(new int(2))); }

上面例子中的代碼當然是正確的,智能指針確實可以這樣用,然而因為某些原因,實際情況中并不這么用。 第一,反復聲明 boost::shared_ptr 需要更多的輸入。 其次,將 boost::shared_ptr 拷進,拷出,或者在容器內部做拷貝,需要頻繁的增加或者減少內部引用計數,這肯定效率不高。 由于這些原因,Boost C++ 庫提供了 指針容器 專門用來管理動態分配的對象。

#include <boost/ptr_container/ptr_vector.hpp> int main() { boost::ptr_vector<int> v; v.push_back(new int(1)); v.push_back(new int(2)); }

boost::ptr_vector 類的定義在 boost/ptr_container/ptr_vector.hpp 里,它跟前一個例子中用 boost::shared_ptr 模板參數來初始化的容器具有相同的工作方式。 boost::ptr_vector 專門用于動態分配的對象,它使用起來更容易也更高效。 boost::ptr_vector 獨占它所包含的對象,因而容器之外的共享指針不能共享所有權,這跟 std::vector<boost::shared_ptr > 相反。

除了 boost::ptr_vector 之外,專門用于管理動態分配對象的容器還包括:boost::ptr_deque, boost::ptr_list, boost::ptr_set, boost::ptr_map, boost::ptr_unordered_set 和 boost::ptr_unordered_map。這些容器等價于C++標準里提供的那些。最后兩個容器對應于std::unordered_set 和 std::unordered_map,它們作為技術報告1的一部分加入 C++ 標準。 如果所使用的 C++ 標準實現不支持技術報告1的話,還可以使用 Boost C++ 庫里實現的 boost::unordered_set 和 boost::unordered_map。

總結

以上是生活随笔為你收集整理的boost C++知识点(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。