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