Cpp / shared_ptr
一、誕生原因
在 C++ 中,一大缺陷是給定一個非空指針,程序并不能確定該指針是否為懸空指針。
為了解決上述問題,boost 庫中誕生了智能指針:shared_ptr、weak_ptr、unique_ptr。
二、設計思想
基于 RALL 思想,即:對象和資源進行綁定,對象創(chuàng)建時獲取資源,對象銷毀時釋放資源,即:對象是資源的代理。
應用到指針管理方面,智能指針創(chuàng)建時引入內(nèi)存地址,智能指針析構(gòu)時釋放內(nèi)存塊。
具體到細節(jié),shared_ptr 智能指針采用所有權(quán)制,即:對內(nèi)存塊采用引用計數(shù)的方式來判斷是否回收,每增加一個 shared_ptr 對該內(nèi)存塊的指向,則引用計數(shù) + 1,每一個 shared_ptr 析構(gòu)時則引用計數(shù)?- 1;當引用計數(shù)為 0 時則 delete 該內(nèi)存塊。
三、栗子
#include <iostream> #include <memory>class Test { public:int i;Test(int n) : i(n){};~Test() { std::cout << i << " "<< "析構(gòu)" << std::endl; } }; int main() {std::shared_ptr<Test> sp1(new Test(2)); // Test(2) 由 sp1 托管。std::shared_ptr<Test> sp2(sp1); // Test(2) 同時交由 sp2 托管。std::shared_ptr<Test> sp3;sp3 = sp2; // Test(2) 同時交由 sp3 托管。std::cout << sp1->i << "," << sp2->i << "," << sp3->i << std::endl;Test *p = sp3.get(); // get 返回托管的指針,p 指向 Test(2)std::cout << p->i << std::endl; //輸出 2sp1.reset(new Test(3)); // reset 導致托管新的指針, 此時 sp1 托管 Test(3),Test(2) 引用計數(shù) - 1 。sp2.reset(new Test(4)); // sp2 托管 Test(4),Test(2) 引用計數(shù) - 1 。std::cout << sp1->i << std::endl; // 輸出 3sp3.reset(new Test(5)); // sp3 托管 Test(5)。Test(2) 引用計數(shù) - 1,此時計數(shù)為0,被 delete 。std::cout << "end" << std::endl;return 0; }結(jié)果
2,2,2 2 3 2 析構(gòu) end 5 析構(gòu) 4 析構(gòu) 3 析構(gòu)四、其他
引用計數(shù) + 1 和 - 1?操作是原子性的,所以線程安全的。
make_shared 要優(yōu)于使用 new,因為 make_shared 可以一次性將需要內(nèi)存分配好。
std::shared_ptr 的大小是原始指針的兩倍,因為它的內(nèi)部有一個原始指針指向資源,同時有個指針指向引用計數(shù)。
引用計數(shù)是分配在動態(tài)分配的,std::shared_ptr 支持拷貝,新的指針獲可以獲取前引用計數(shù)個數(shù)。?
?
(SAW:Game Over!)
總結(jié)
以上是生活随笔為你收集整理的Cpp / shared_ptr的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cpp 11 / override 和
- 下一篇: C/Cpp / 野指针和悬空指针