std::shared_ptr
智慧型指標是c++11乙個相當重要的特性,可以極大地將開發者從資源申請/釋放的繁重勞動中解放出來。
然而直到c++17前std::shared_ptr
都有乙個嚴重的限制,那就是它並不支援動態陣列:
#include std::shared_ptrsp1(new int[10]()); // 錯誤,c++17前不能傳遞陣列型別作為shared_ptr的模板引數
std::unique_ptrup1(new int[10]()); // ok, unique_ptr對此做了特化
std::shared_ptrsp2(new int[10]()); // 錯誤,可以編譯,但會產生未定義行為,請不要這麼做
sp1
錯誤的原因很明顯,然而sp2
的就沒有那麼好找了,究其原因,是因為std::shared_ptr
對非陣列型別都使用delete p
釋放資源,顯然這對於new int[10]
來說是不對的,對它應該使用delete p
。
其實c++17前的解決方案並不複雜,我們可以借助std::default_delete
,它用於提供對應型別的正確的delete操作:
std::shared_ptrsp3(new int[10](), std::default_delete());
現在我們提供了正確的delete操作,可以放心地使用了。
不過這麼做的缺點也是很明顯的:
我們想管理的值是int型別的,然而事實上傳給模板引數的是int
需要顯示提供delete functor
不能使用std::make_shared
,無法保證異常安全
c++17前shared_ptr未提供opreator
,所以當需要類似操作時不得不使用sp3.get()[index]
的形式
事實上共享一片連續分配記憶體的需求是極為常見的,所以為了修正上述缺陷,c++17以及即將推出的c++2a對std::shared_ptr
做了完善。
先說c++17的改進,shared_ptr增加了opreator
,並可以使用int
類的陣列型別做模板引數,所以sp3
的定義可以簡化了:
std::shared_ptrsp3(new int[10]());
對於訪問分配的空間,可以將sp3.get()[index]
替換為sp3[index]
。看個具體的例子:
#include #include int main()
for (int i = 0; i < 5; ++i)
}
我們分配乙個有5個int元素的動態陣列,然後分別賦值1-5的平方,然後輸出:
g++ -wall -std=c++17 test.cpp
./a.out14
91625
使用被極大得簡化了,然而還是有點問題,那就是無法使用std::make_shared
,而我們除非指定自己的delete functor,否則我們應該盡量使用std::make_shared
。
所以c++20對此做了改進:
auto up2 = std::make_unique(10); // 從c++14開始,分配乙個管理有10個int元素的動態陣列的unique_ptr
// c++2a中你可以這樣寫,與上一句相似,只不過返回的是shared_ptr
auto sp3 = std::make_shared(10);
在我的編譯器上(gcc 8.2.1)還不能支援這一特性,所以很遺憾得不能提供演示了。
不過等c++2a(很可能就叫c++20)發布後std::shared_ptr
就能安全而便捷地管理動態陣列了。
weak ptr和shared ptr功能總結
結構分析 weak ptr和shared ptr都包含乙個 m refcount資料成員,追溯其定義,內部包含乙個 sp counted base lp m pi。shared ptr能夠實現其功能依賴於對於多個shared ptr只例項化乙個 sp counted base lp 當我們通過某一s...
shared ptr的使用和陷阱
make shared分配一塊int型別大小的記憶體,並值初始化為100 返回值是shared ptr型別,因此可以直接賦值給sp shared ptr sp make shared 100 錯誤!不會進行隱式轉換,型別不符合 shared ptr sp1 new int 100 正確,直接初始化呼...
shared ptr 和auto ptr智慧型指標
shared ptr 計數的智慧型指標 它是乙個包裝了new操作符在堆上分配的動態物件,但它實現的是引用計數型的智慧型指標 可以被自由地拷貝和賦值,在任意的地方共享它,當沒有 使用 引用計數為0 它時才刪除被包裝的動態分配的物件。shared ptr也可以安全地放到標準容器中,並彌補了auto pt...