網(wǎng)站首頁 編程語言 正文
一、提要
boost::shared_ptr是另一個(gè)智能指針,與 boost::scoped_ptr有很大不同,本文闡述這種區(qū)別。
二、智能指針boost::shared_ptr與boost::scoped_ptr
主要區(qū)別在于:
- boost::shared_ptr 不一定是對(duì)象的獨(dú)占所有者。
- 所有權(quán)可以與 boost::shared_ptr 類型的其他智能指針共享。在這種情況下,共享對(duì)象不會(huì)被釋放,直到引用該對(duì)象的共享指針的最后一個(gè)副本被銷毀。
- 因?yàn)?boost::shared_ptr 可以共享所有權(quán),所以可以復(fù)制智能指針,而這對(duì)于 boost::scoped_ptr 是不可能的。
boost::shared_ptr
定義在boost/shared_ptr.hpp
.
三、智能指針 boost::shared_ptr用法
示例1
基本調(diào)用boost::shared_ptr
示例 1
#include <boost/shared_ptr.hpp> #include <iostream> int main() { boost::shared_ptr<int> p1{new int{1}}; std::cout << *p1 << '\n'; boost::shared_ptr<int> p2{p1}; p1.reset(new int{2}); std::cout << *p1.get() << '\n'; p1.reset(); std::cout << std::boolalpha << static_cast<bool>(p2) << '\n'; }
示例 1 使用了 boost::shared_ptr 類型的兩個(gè)智能指針 p1 和 p2。 p2 用 p1 初始化,這意味著兩個(gè)智能指針共享同一個(gè) int 對(duì)象的所有權(quán)。當(dāng)在 p1 上調(diào)用 reset() 時(shí),一個(gè)新的 int 對(duì)象被錨定在 p1 中。這并不意味著現(xiàn)有的 int 對(duì)象被銷毀。由于它也錨定在 p2 中,因此它繼續(xù)存在。在調(diào)用 reset() 之后,p1 是編號(hào)為 2 的 int 對(duì)象的唯一所有者,而 p2 是編號(hào)為 1 的 int 對(duì)象的唯一所有者。
boost::shared_ptr 在內(nèi)部使用引用計(jì)數(shù)器。只有當(dāng) boost::shared_ptr 檢測(cè)到智能指針的最后一個(gè)副本已被銷毀時(shí),才會(huì)使用 delete 釋放包含的對(duì)象。
與 boost::scoped_ptr 一樣,boost::shared_ptr 重載 operator bool()、operator*() 和 operator->()。成員函數(shù) get() 和 reset() 用于檢索當(dāng)前存儲(chǔ)的地址或存儲(chǔ)新地址。
作為第二個(gè)參數(shù),可以將刪除器傳遞給 boost::shared_ptr 的構(gòu)造函數(shù)。刪除器必須是一個(gè)函數(shù)或函數(shù)對(duì)象,它接受實(shí)例化時(shí)使用的 boost::shared_ptr 類型的指針作為其唯一參數(shù)。在析構(gòu)函數(shù)中調(diào)用刪除器而不是刪除。這使得管理 boost::shared_ptr 中動(dòng)態(tài)分配的對(duì)象以外的資源成為可能。
示例2
boost::shared_ptr
用戶自定義刪除
示例 2
#include <boost/shared_ptr.hpp> #include <Windows.h> int main() { boost::shared_ptr<void> handle(OpenProcess(PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId()), CloseHandle); }
在示例2 boost::shared_ptr 被實(shí)例化為 void。傳遞給構(gòu)造函數(shù)的第一個(gè)參數(shù)是 OpenProcess() 的返回值。 OpenProcess() 是一個(gè)用于獲取進(jìn)程句柄的 Windows 函數(shù)。在示例中,OpenProcess() 返回當(dāng)前進(jìn)程的句柄 - 示例本身。
Windows 使用句柄來引用資源。一旦不再使用資源,必須使用 CloseHandle() 關(guān)閉句柄。 CloseHandle() 期望的唯一參數(shù)是要關(guān)閉的句柄。在示例中,CloseHandle() 作為第二個(gè)參數(shù)傳遞給 boost::shared_ptr 的構(gòu)造函數(shù)。 CloseHandle() 是句柄的刪除器。當(dāng)在 main() 結(jié)束時(shí)銷毀句柄時(shí),析構(gòu)函數(shù)調(diào)用 CloseHandle() 以關(guān)閉作為第一個(gè)參數(shù)傳遞給構(gòu)造函數(shù)的句柄。
示例2 之所以有效,是因?yàn)?Windows 句柄被定義為 void*。如果 OpenProcess() 沒有返回 void* 類型的值,并且如果 CloseHandle() 沒有預(yù)期 void* 類型的參數(shù),則無法在此示例中使用 boost::shared_ptr。刪除器不會(huì)使 boost::shared_ptr 成為管理任意資源的靈丹妙藥。
示例3
用boost::make_shared
#include <boost/make_shared.hpp> #include <typeinfo> #include <iostream> int main() { auto p1 = boost::make_shared<int>(1); std::cout << typeid(p1).name() << '\n'; auto p2 = boost::make_shared<int[]>(10); std::cout << typeid(p2).name() << '\n'; }
Boost.SmartPointers 在 boost/make_shared.hpp 中提供了一個(gè)輔助函數(shù) boost::make_shared()。使用 boost::make_shared(),您可以創(chuàng)建 boost::shared_ptr 類型的智能指針,而無需自己調(diào)用 boost::shared_ptr 的構(gòu)造函數(shù)。
boost::make_shared() 的優(yōu)點(diǎn)是必須動(dòng)態(tài)分配的對(duì)象內(nèi)存和智能指針內(nèi)部使用的引用計(jì)數(shù)器的內(nèi)存可以保留在一個(gè)塊中。使用 boost::make_shared() 比調(diào)用 new 來創(chuàng)建動(dòng)態(tài)分配的對(duì)象并在 boost::shared_ptr 的構(gòu)造函數(shù)中再次調(diào)用 new 來為引用計(jì)數(shù)器分配內(nèi)存更有效。
您也可以對(duì)數(shù)組使用 boost::make_shared()。在示例 1.5 中第二次調(diào)用 boost::make_shared() 時(shí),一個(gè)具有十個(gè)元素的 int 數(shù)組被錨定在 p2 中。
boost::shared_ptr 自 Boost 1.53.0 起僅支持?jǐn)?shù)組。 boost::shared_array 提供了一個(gè)類似于 boost::shared_ptr 的智能指針,就像 boost::scoped_array 類似于 boost::scoped_ptr 一樣。當(dāng)使用 Visual C++ 2013 和 Boost 1.53.0 或更高版本構(gòu)建時(shí),示例 1.5 為 p2 打印 class boost::shared_ptr<int [0]>。
從 Boost 1.53.0 開始,boost::shared_ptr 支持單個(gè)對(duì)象和數(shù)組,并檢測(cè)是否必須使用 delete 或 delete[] 釋放資源。因?yàn)?boost::shared_ptr 還重載了 operator[](自 Boost 1.53.0 起),所以這個(gè)智能指針是 boost::shared_array 的替代方案。
示例4
用boost::shared_array
Example 4 .Using
#include <boost/shared_array.hpp> #include <iostream> int main() { boost::shared_array<int> p1{new int[1]}; { boost::shared_array<int> p2{p1}; p2[0] = 1; } std::cout << p1[0] << '\n'; }
boost::shared_array 補(bǔ)充 boost::shared_ptr:由于 boost::shared_array 在析構(gòu)函數(shù)中調(diào)用 delete[],所以這個(gè)智能指針可以用于數(shù)組。對(duì)于早于 Boost 1.53.0 的版本,boost::shared_array 必須用于數(shù)組,因?yàn)?boost::shared_ptr 不支持?jǐn)?shù)組。
boost::shared_array 在 boost/shared_array.hpp 中定義。
在示例4 中,智能指針 p1 和 p2 共享動(dòng)態(tài)分配的 int 數(shù)組的所有權(quán)。當(dāng)使用 operator[] 訪問 p2 中的數(shù)組以存儲(chǔ)數(shù)字 1 時(shí),使用 p1 訪問相同的數(shù)組。因此,該示例將 1 寫入標(biāo)準(zhǔn)輸出。
與 boost::shared_ptr 一樣,boost::shared_array 使用引用計(jì)數(shù)器。當(dāng) p2 被銷毀時(shí),動(dòng)態(tài)分配的數(shù)組不會(huì)被釋放,因?yàn)?p1 仍然包含對(duì)該數(shù)組的引用。只有當(dāng) p1 的作用域結(jié)束時(shí),該數(shù)組才會(huì)在 main() 結(jié)束時(shí)被銷毀。
boost::shared_array 還提供了成員函數(shù) get() 和 reset()。此外,它使運(yùn)算符 operator bool 過載。
示例5
用boost::shared_ptr
和BOOST_SP_USE_QUICK_ALLOCATOR
Example5.boost::shared_ptr
和BOOST_SP_USE_QUICK_ALLOCATOR
#define BOOST_SP_USE_QUICK_ALLOCATOR #include <boost/shared_ptr.hpp> #include <iostream> #include <ctime> int main() { boost::shared_ptr<int> p; std::time_t then = std::time(nullptr); for (int i = 0; i < 1000000; ++i) p.reset(new int{i}); std::time_t now = std::time(nullptr); std::cout << now - then << '\n'; }
選擇像 boost::shared_ptr 這樣的智能指針而不是標(biāo)準(zhǔn)庫中的智能指針是有意義的。 Boost.SmartPointers 支持宏來優(yōu)化智能指針的行為。示例 5 使用宏 BOOST_SP_USE_QUICK_ALLOCATOR 來激活 Boost.SmartPointers 附帶的分配器。此分配器管理內(nèi)存塊以減少對(duì)引用計(jì)數(shù)器的 new 和 delete 調(diào)用次數(shù)。該示例調(diào)用 std::time() 來測(cè)量循環(huán)前后的時(shí)間。雖然執(zhí)行循環(huán)所需的時(shí)間取決于計(jì)算機(jī),但使用BOOST_SP_USE_QUICK_ALLOCATOR 的示例可能會(huì)比不使用時(shí)運(yùn)行得更快。 Boost.SmartPointers 的文檔沒有提到 BOOST_SP_USE_QUICK_ALLOCATOR。因此,您應(yīng)該分析您的程序并比較使用和不使用 BOOST_SP_USE_QUICK_ALLOCATOR 獲得的結(jié)果。
Chapter1.Boost.SmartPointers - Shared Ownership (theboostcpplibraries.com)
原文鏈接:https://yamagota.blog.csdn.net/article/details/127045943
相關(guān)推薦
- 2022-11-12 asp.net?web?api2設(shè)置默認(rèn)啟動(dòng)登錄頁面的方法_實(shí)用技巧
- 2022-07-21 C語言全面細(xì)致講解單雙精度float與double的使用方法_C 語言
- 2022-06-20 一文搞懂Python的hasattr()、getattr()、setattr()?函數(shù)用法_pyth
- 2022-06-12 C語言實(shí)例真題講解數(shù)據(jù)結(jié)構(gòu)中單向環(huán)形鏈表_C 語言
- 2022-02-25 .gitignore 中增加了 .idea/ workspace.xml失效解決方案
- 2022-06-01 C語言超詳細(xì)講解棧與隊(duì)列實(shí)現(xiàn)實(shí)例_C 語言
- 2022-08-21 Go語言的互斥鎖的詳細(xì)使用_Golang
- 2023-04-03 python之語句mode?=?'test'?if?y?is?None?else?'train'問題
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支