<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          #Boost# Boost 智能指針

          共 8345字,需瀏覽 17分鐘

           ·

          2022-11-17 16:47

           文章所涉及內(nèi)容更多來自網(wǎng)絡(luò),在此聲明,并感謝知識(shí)的貢獻(xiàn)者!

          Boost 簡(jiǎn)介

          Boost簡(jiǎn)介
          http://zh.highscore.de/cpp/boost/introduction.html


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

          C++ 標(biāo)準(zhǔn) 智能指針 auto_ptr
          C++標(biāo)準(zhǔn)只提供了一種智能指針: std::auto_ptr。
          它基本上就像是個(gè)普通的指針: 通過地址來訪問一個(gè)動(dòng)態(tài)分配的對(duì)象。 std::auto_ptr之所以被看作是智能指針,是因?yàn)樗鼤?huì)在析構(gòu)的時(shí)候調(diào)用 delete 操作符來自動(dòng)釋放所包含的對(duì)象。 當(dāng)然這要求在初始化的時(shí)候,傳給它一個(gè)由 new 操作符返回的對(duì)象的地址。 既然 std::auto_ptr 的析構(gòu)函數(shù)會(huì)調(diào)用 delete 操作符,它所包含的對(duì)象的內(nèi)存會(huì)確保釋放掉。

          RAII 機(jī)制

          RAII機(jī)制 :資源申請(qǐng)即初始化。
          智能指針確保在任何情況下,動(dòng)態(tài)分配的內(nèi)存都能得到正確釋放。用一個(gè)動(dòng)態(tài)分配的對(duì)象的地址來初始化智能指針,在析構(gòu)的時(shí)候釋放內(nèi)存,就確保了這一點(diǎn)。 因?yàn)槲鰳?gòu)函數(shù)總是會(huì)被執(zhí)行的,這樣所包含的內(nèi)存也將總是會(huì)被釋放。
          #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);
          }
          通過 OpenProcess() 打開的資源不需要顯示的調(diào)用 CloseHandle() 來關(guān)閉。 當(dāng)然,應(yīng)用程序終止時(shí)資源也會(huì)隨之關(guān)閉。 然而,在更加復(fù)雜的應(yīng)用程序里, windows_handle 類確保當(dāng)一個(gè)資源不再使用時(shí)就能正確的關(guān)閉。 某個(gè)資源一旦離開了它的作用域——上例中 h 的作用域在 main()函數(shù)的末尾——它的析構(gòu)函數(shù)會(huì)被自動(dòng)的調(diào)用,相應(yīng)的資源也就釋放掉了。

          作用域指針 scoped_ptr

          作用域指針
          一個(gè)作用域指針獨(dú)占一個(gè)動(dòng)態(tài)分配的對(duì)象,對(duì)應(yīng)的類名為 boost::scoped_ptr。一個(gè)作用域指針不能傳遞它所包含的對(duì)象的所有權(quán)到另一個(gè)作用域指針。 一旦用一個(gè)地址來初始化,這個(gè)動(dòng)態(tài)分配的對(duì)象將在析構(gòu)階段釋放。因?yàn)橐粋€(gè)作用域指針只是簡(jiǎn)單保存和獨(dú)占一個(gè)內(nèi)存地址,所以 boost::scoped_ptr的實(shí)現(xiàn)就要比 std::auto_ptr 簡(jiǎn)單。 在不需要所有權(quán)傳遞的時(shí)候應(yīng)該優(yōu)先使用 boost::scoped_ptr 。 在這些情況下,比起 std::auto_ptr 它是一個(gè)更好的選擇,因?yàn)榭梢员苊獠唤?jīng)意間的所有權(quán)傳遞。
          #include <boost/scoped_ptr.hpp>
          int main()
          {
          boost::scoped_ptr<int> i(new int);
          *i = 1;
          *i.get() = 2;
          i.reset(new int);
          }
          一經(jīng)初始化,智能指針 boost::scoped_ptr 所包含的對(duì)象,可以通過類似于普通指針的接口來訪問。get() 和 reset() 方法:前者返回所含對(duì)象的地址,后者用一個(gè)新的對(duì)象來重新初始化智能指針。 在這種情況下,新創(chuàng)建的對(duì)象賦值之前會(huì)先自動(dòng)釋放所包含的對(duì)象。boost::scoped_ptr 的析構(gòu)函數(shù)中使用delete 操作符來釋放所包含的對(duì)象。 這對(duì) boost::scoped_ptr所包含的類型加上了一條重要的限制。

          作用域數(shù)組
          作用域數(shù)組的使用方式與作用域指針相似。 關(guān)鍵不同在于,作用域數(shù)組的析構(gòu)函數(shù)使用 delete[]操作符來釋放所包含的對(duì)象。 因?yàn)樵摬僮鞣荒苡糜跀?shù)組對(duì)象,所以作用域數(shù)組必須通過動(dòng)態(tài)分配的數(shù)組來初始化。
          對(duì)應(yīng)的作用域數(shù)組類名為 boost::scoped_array
          #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]);
          }
          可以通過 operator[]() 操作符訪問數(shù)組中特定的元素,boost:scoped_array 也提供了 get() 和 reset() 方法,用來返回和重新初始化所含對(duì)象的地址。

          共享指針 shared_ptr

          共享指針
          智能指針 boost::shared_ptr 基本上類似于 boost::scoped_ptr。 關(guān)鍵不同之處在于 boost::shared_ptr不一定要獨(dú)占一個(gè)對(duì)象。 它可以和其他 boost::shared_ptr 類型的智能指針共享所有權(quán)。 在這種情況下,當(dāng)引用對(duì)象的最后一個(gè)智能指針銷毀后,對(duì)象才會(huì)被釋放。
          因?yàn)樗袡?quán)可以在 boost::shared_ptr 之間共享,任何一個(gè)共享指針都可以被復(fù)制,這跟boost::scoped_ptr 是不同的。 這樣就可以在標(biāo)準(zhǔn)容器里存儲(chǔ)智能指針了——你不能在標(biāo)準(zhǔn)容器中存儲(chǔ) std::auto_ptr,因?yàn)樗鼈冊(cè)诳截惖臅r(shí)候傳遞了所有權(quán)。
          #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 能夠共享它所含對(duì)象的所有權(quán),所以保存在容器中的拷貝(包括容器在需要時(shí)額外創(chuàng)建的拷貝)都是和原件相同的。

          共享數(shù)組
          共享數(shù)組的行為類似于共享指針。 關(guān)鍵不同在于共享數(shù)組在析構(gòu)時(shí),默認(rèn)使用 delete[]操作符來釋放所含的對(duì)象。 因?yàn)檫@個(gè)操作符只能用于數(shù)組對(duì)象,共享數(shù)組必須通過動(dòng)態(tài)分配的數(shù)組的地址來初始化。
          共享數(shù)組對(duì)應(yīng)的類型是 boost::shared_array
          #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;
          }
          就像共享指針那樣,所含對(duì)象的所有權(quán)可以跟其他共享數(shù)組來共享。 這個(gè)例子中定義了2個(gè)變量i1 和 i2,它們引用到同一個(gè)動(dòng)態(tài)分配的數(shù)組。i1 通過 operator[]() 操作符保存了一個(gè)整數(shù)1——這個(gè)整數(shù)可以被 i2 引用,比如打印到標(biāo)準(zhǔn)輸出。boost::shared_array 也同樣提供了 get() 和 reset() 方法。 另外還重載了 operator bool()。

          弱指針 weak_ptr

          弱指針
          弱指針只有在配合共享指針一起使用時(shí)才有意義。 弱指針 boost::weak_ptr
          #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 來初始化的。一旦初始化之后,它基本上只提供一個(gè)有用的方法: lock()。此方法返回的boost::shared_ptr 與用來初始化弱指針的共享指針共享所有權(quán)。 如果這個(gè)共享指針不含有任何對(duì)象,返回的共享指針也將是空的。
          當(dāng)函數(shù)需要一個(gè)由共享指針?biāo)芾淼膶?duì)象,而這個(gè)對(duì)象的生存期又不依賴于這個(gè)函數(shù)時(shí),就可以使用弱指針。 只要程序中還有一個(gè)共享指針掌管著這個(gè)對(duì)象,函數(shù)就可以使用該對(duì)象。 如果共享指針復(fù)位了,就算函數(shù)里能得到一個(gè)共享指針,對(duì)象也不存在了。
          上例的 main() 函數(shù)中,通過Windows API 創(chuàng)建了2個(gè)線程。 于是乎,該例只能在Windows 平臺(tái)上編譯運(yùn)行。
          第一個(gè)線程函數(shù) reset() 的參數(shù)是一個(gè)共享指針的地址。 第二個(gè)線程函數(shù)print() 的參數(shù)是一個(gè)弱指針的地址。 這個(gè)弱指針是之前通過共享指針初始化的。
          一旦程序啟動(dòng)之后,reset() 和 print()就都開始執(zhí)行了。 不過執(zhí)行順序是不確定的。 這就導(dǎo)致了一個(gè)潛在的問題:reset() 線程在銷毀對(duì)象的時(shí)候print() 線程可能正在訪問它。
          通過調(diào)用弱指針的 lock() 函數(shù)可以解決這個(gè)問題:如果對(duì)象存在,那么lock() 函數(shù)返回的共享指針指向這個(gè)合法的對(duì)象。否則,返回的共享指針被設(shè)置為0,這等價(jià)于標(biāo)準(zhǔn)的null指針。
          弱指針本身對(duì)于對(duì)象的生存期沒有任何影響。 lock() 返回一個(gè)共享指針,print() 函數(shù)就可以安全的訪問對(duì)象了。 這就保證了——即使另一個(gè)線程要釋放對(duì)象——由于我們有返回的共享指針,對(duì)象依然存在。

          介入式指針 intrusive_ptr

          介入式指針
          介入式指針boost::intrusive_ptr的工作方式和共享指針完全一樣。boost::shared_ptr 在內(nèi)部記錄著引用到某個(gè)對(duì)象的共享指針的數(shù)量,可是對(duì)介入式指針來說,程序員就得自己來做記錄。 對(duì)于框架對(duì)象來說這就特別有用,因?yàn)樗鼈冇涗浿陨肀灰玫拇螖?shù)。
          #include <boost/intrusive_ptr.hpp>
          #include <atlbase.h>
          #include <iostream>
          void intrusive_ptr_add_ref(IDispatch *p)
          {
          p->AddRef();
          }
          void intrusive_ptr_release(IDispatch *p)
          {
          p->Release();
          }
          void check_windows_folder()
          {
          CLSID clsid;
          CLSIDFromProgID(CComBSTR("Scripting.FileSystemObject"), &clsid);
          void *p;
          CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, __uuidof(IDispatch), &p);
          boost::intrusive_ptr<IDispatch> disp(static_cast<IDispatch*>(p));
          CComDispatchDriver dd(disp.get());
          CComVariant arg("C:\\Windows");
          CComVariant ret(false);
          dd.Invoke1(CComBSTR("FolderExists"), &arg, &ret);
          std::cout << (ret.boolVal != 0) << std::endl;
          }
          void main()
          {
          CoInitialize(0);
          check_windows_folder();
          CoUninitialize();
          }
          COM 對(duì)象是使用 boost::intrusive_ptr的絕佳范例,因?yàn)?COM 對(duì)象需要記錄當(dāng)前有多少指針引用著它。 通過調(diào)用 AddRef() 和 Release() 函數(shù),內(nèi)部的引用計(jì)數(shù)分別增 1 或者減 1。當(dāng)引用計(jì)數(shù)為 0 時(shí),COM 對(duì)象自動(dòng)銷毀。
          在 intrusive_ptr_add_ref() 和 intrusive_ptr_release() 內(nèi)部調(diào)用 AddRef() 和Release() 這兩個(gè)函數(shù),來增加或減少相應(yīng) COM 對(duì)象的引用計(jì)數(shù)。

          指針容器 ptr_vector

          指針容器
          #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 專門用于動(dòng)態(tài)分配的對(duì)象,它使用起來更容易也更高效。boost::ptr_vector 獨(dú)占它所包含的對(duì)象,因而容器之外的共享指針不能共享所有權(quán),這跟 std::vector<boost::shared_ptr<int> > 相反。
          除了 boost::ptr_vector 之外,專門用于管理動(dòng)態(tài)分配對(duì)象的容器還包括:boost::ptr_deque, boost::ptr_list, boost::ptr_set, boost::ptr_map, boost::ptr_unordered_set 和 boost::ptr_unordered_map。這些容器等價(jià)于C++標(biāo)準(zhǔn)里提供的那些。


          瀏覽 49
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  豆花视频一区二区三区在线观看 | 人人澡人人爽人人精品 | 婷婷在线综合激情 | 天天操天天干天天爽 | 青娱乐偷拍视频 |