智能指针的总结
文章目錄
- 定義
- 分類
- 智能指針的使用
- `shared_ptr`
- `weak_ptr`
- `unique_ptr`
- 常見(jiàn)的陷阱
- 總結(jié)
- 參考地址
定義
智能指針是對(duì)象,不是指針。它是通過(guò)c++的RAII機(jī)制實(shí)現(xiàn)的,主要是利用c++對(duì)象在釋放資源的時(shí)候,會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù)這一特性。
分類
auto_ptr: 智能指針,c++11已經(jīng)停用;
shared_ptr: 強(qiáng)智能指針,可以改變資源的引用計(jì)數(shù);
weak_ptr: 弱智能指針,不會(huì)改變資源的引用計(jì)數(shù);
unique_ptr: 獨(dú)占式強(qiáng)智能指針,只能轉(zhuǎn)移,不能重新賦值;
智能指針的使用
shared_ptr
原理
shared_ptr采用了引用計(jì)數(shù)器,允許多個(gè)指針指向同一個(gè)對(duì)象。每一個(gè)shared_ptr的拷貝都指向相同的內(nèi)存,并共同維護(hù)同一個(gè)引用計(jì)數(shù)器,記錄統(tǒng)一使用被引用的次數(shù)。每增加一個(gè)shared_ptr智能指針對(duì)象,new對(duì)象指針的引用計(jì)數(shù)上就加1,當(dāng)shared_ptr智能指針失效時(shí),new對(duì)象指針的引用計(jì)數(shù)就減1。引用計(jì)數(shù)歸0時(shí),shared_ptr會(huì)釋放管理的內(nèi)存空間。
shared_ptr包含2個(gè)指針,一個(gè)是指向管理的內(nèi)存空間,一個(gè)是指向內(nèi)存的控制塊。
內(nèi)存控制塊包含引用計(jì)數(shù)器,刪除器,分配器等。
class Test { public:Test();~Test();void setFather(std::shared_ptr<Test> &value) {m_father = value;}void setSon(std::shared_ptr<Test> &value) {m_son = value;}private:std::shared_ptr<Test> m_father;std::shared_ptr<Test> m_son; };void test() {Test *ps = new Test();std::shared_ptr<Test> ptr1(ps);std::shared_ptr<Test> ptr2(ps);ptr1->setFather(ptr2);ptr2->setSon(ptr1);//計(jì)數(shù)std::cout << ptr1.use_count() << endl;//計(jì)數(shù)std::cout << ptr2.use_count() << endl;//計(jì)數(shù)獲取原始指針std::cout << ptr1.get() <<endl;std::cout << ptr2.get() <<endl; }輸出: Test Construct() 2 2 0xfe1740 0xfe1740從輸出信息中可以看到并未調(diào)用析構(gòu)函數(shù)。主要是因?yàn)榛ハ嘁脤?dǎo)致。
示例2 測(cè)試引用計(jì)數(shù)問(wèn)題
//測(cè)試shared_ptr的引用計(jì)數(shù) void testSharedPtrCount() {//不要使用該方式初始化Test *ps = new Test();std::shared_ptr<Test> ptr1(ps);std::shared_ptr<Test> ptr2(ps);//計(jì)數(shù)std::cout << ptr1.use_count() << endl;std::cout << ptr2.use_count() << endl;std::shared_ptr<Test> ptr3(new Test());std::shared_ptr<Test> ptr4 = ptr3;//計(jì)數(shù)std::cout << ptr3.use_count() << endl;std::cout << ptr4.use_count() << endl; }輸出: 1 1 2 2可以看到使用同一個(gè)對(duì)象指針初始化的時(shí)候,引用計(jì)數(shù)為1,而使用智能指針初始化智能指針后,引用計(jì)數(shù)均為2。
智能指針的頭文件為:#include
weak_ptr
weak_ptr不能單獨(dú)作為智能指針使用,只能輔助shared_ptr解決循環(huán)依賴的問(wèn)題。
定義對(duì)象的時(shí)候使用shared_ptr,引用對(duì)象的時(shí)候使用weak_ptr。
修改shared_ptr的代碼為:
class Test { public:Test();~Test();void setFather(std::shared_ptr<Test> &value) {m_father = value;}void setSon(std::shared_ptr<Test> &value) {m_son = value;}private://修改對(duì)象的引用為weak_ptrstd::weak_ptr<Test> m_father;std::weak_ptr<Test> m_son; };輸出: Test Construct() 1 1 0x1091740 0x1091740 Test Destruct() Test Destruct()可以看到析構(gòu)函數(shù)被調(diào)用了。(即使析構(gòu)了2次,部分編譯器可能不會(huì)出現(xiàn)析構(gòu)錯(cuò)誤信息)
unique_ptr
unique_ptr是獨(dú)占型的強(qiáng)智能指針。獨(dú)占型就是不允許多個(gè)智能指針指向同一塊內(nèi)存空間,也不支持拷貝,復(fù)制。
示例1 獨(dú)占性
//測(cè)試uniqueptr void testUniquePtr() {Test *ps = new Test();std::unique_ptr<Test> ptr1(ps);//編譯期間就出現(xiàn)錯(cuò)誤std::unique_ptr<Test> ptr2 = ptr1;std::cout << ptr1.get() << endl;std::cout << ptr2.get() << endl; }**示例2 move **
//測(cè)試unique_ptr的轉(zhuǎn)移 void testUniquePtrMove() {Test *ps = new Test();std::unique_ptr<Test> ptr1(ps);std::cout << "Ptr1: " << ptr1.get() << endl;std::unique_ptr<Test> ptr2(ps);ptr2 = std::move(ptr1);std::cout << "Ptr1: " << ptr1.get() << endl;std::cout << "Ptr2: " << ptr2.get() << endl; }//輸出 Test Construct() Ptr1: 0x761740 Test Destruct() Ptr1: 0 Ptr2: 0x761740 Test Destruct()可以看出調(diào)用move()后,ptr1被置為nullptr(0), ptr2被設(shè)置為0x761740。
常見(jiàn)的陷阱
-
不要使用指針初始化多個(gè)智能指針。
-
不要delete get()返回的指針。
總結(jié)
參考地址
C++ 智能指針
c++智能指針
C++智能指針的使用(非常詳細(xì))
C++智能指針詳解
總結(jié)
- 上一篇: 解决使用支付宝沙箱应用报错wrong t
- 下一篇: nextcloud配置mysql_nex