瀘州市住房與城鄉(xiāng)建設(shè)局網(wǎng)站google免費(fèi)入口
介紹
shared_ptr是一種智能指針(smart pointer),作用有如同指針,但會(huì)記錄有多少個(gè)shared_ptrs共同指向一個(gè)對(duì)象。這便是所謂的引用計(jì)數(shù)(reference counting),比如我們把只能指針賦值給另外一個(gè)對(duì)象,那么對(duì)象多了一個(gè)智能指針指向它,所以這個(gè)時(shí)候引用計(jì)數(shù)會(huì)增加一個(gè),我們可以用shared_ptr.use_count()函數(shù)查看這個(gè)智能指針的引用計(jì)數(shù)。
下面放上c++參考手冊(cè)的介紹:
具體對(duì)應(yīng)模塊參考鏈接:https://zh.cppreference.com/w/cpp/memory/shared_ptr
示例:
#include <iostream>
#include <memory> //使用shared_ptr需要include它int main() {//通過(guò)make_shared創(chuàng)建shared_ptrstd::shared_ptr<int> p1 = std::make_shared<int>();*p1 = 78;std::cout << "p1 = " << *p1 << std::endl;//查看引用計(jì)數(shù)std::cout << "p1 Reference count = " << p1.use_count() << std::endl;//第二個(gè)shared_ptr也將在內(nèi)部指向相同的指針//這將會(huì)使引用計(jì)數(shù)變?yōu)?std::shared_ptr<int> p2(p1);//查看引用計(jì)數(shù)std::cout << "p2 Reference count = " << p2.use_count() << std::endl;std::cout << "p1 Reference count = " << p1.use_count() << std::endl;//比較智能指針if (p1 == p2) {std::cout << "p1 and p2 are pointing to same pointer\n";}std::cout << "Reset p1" << std::endl;//重置shared_ptr,在這種情況下,其內(nèi)部不會(huì)指向內(nèi)部的任何指針//因此其引用計(jì)數(shù)將會(huì)變?yōu)?p1.reset();std::cout << "p1 Reference Count = " << p1.use_count() << std::endl;//重置shared_ptr,在這種情況下,其內(nèi)部將會(huì)指向一個(gè)新的指針//因此其引用計(jì)數(shù)將會(huì)變?yōu)?p1.reset(new int(11));std::cout << "p1 Reference Count = " << p1.use_count() << std::endl;//分配nullptr將取消關(guān)聯(lián)指針并使其指向空值p1 = nullptr; std::cout << "p1 Reference Count = " << p1.use_count() << std::endl;if (!p1) {std::cout << "p1 is NULL" << std::endl;}return 0;
}
輸出:
p1 = 78
p1 Reference count = 1
p2 Reference count = 2
p1 Reference count = 2
p1 and p2 are pointing to same pointer
Reset p1
p1 Reference Count = 0
p1 Reference Count = 1
p1 Reference Count = 0
p1 is NULL
下面討論下怎樣使用 std::shared_ptr自定義Deleter.
當(dāng)一個(gè)shared_ptr對(duì)象超出作用域時(shí),其析構(gòu)函數(shù)被調(diào)用,在析構(gòu)函數(shù)中,將其引用計(jì)數(shù)減1,如果引用計(jì)數(shù)的值變?yōu)?,則刪除關(guān)聯(lián)的原始指針。
要?jiǎng)h除析構(gòu)函數(shù)中的內(nèi)部原始指針,默認(rèn)情況下,shared_ptr調(diào)用delete()函數(shù),即
delete Pointer;
但是,我們?cè)谖鰳?gòu)函數(shù)中并不總是要使用delete函數(shù),還可能有其他的需求。
如果shared_ptr指向一個(gè)數(shù)組而不是一個(gè)簡(jiǎn)單的指針
std::shared_ptr<int> p3(new int[12]);
在其析構(gòu)函數(shù)中,shared_ptr將會(huì)調(diào)用 delete
函數(shù)來(lái)刪除int數(shù)組,而正確的方式是使用 delete []
增加定制deleter到shared_ptr
在這種情況下,我們可以將一個(gè)回調(diào)傳遞給shared_ptr的構(gòu)造函數(shù),該構(gòu)造函數(shù)將會(huì)在其析構(gòu)函數(shù)中被調(diào)用
定制Deleter作為函數(shù)指針
//函數(shù)調(diào)用接收到的指針上的delete[]
void deleter(Sample *x){std::cout<<"DELETE FUNCTION CALLED\n";delete[] x;
}
在shared_ptr的構(gòu)造函數(shù)中傳遞函數(shù)指針,以提供自定義的deleter
//使用定制deleter創(chuàng)建sharedptr
std::shared_ptr<Sample> p3(new Sample[12], deleter);
完整的例子如下:
#include <iostream>
#include <memory>struct Sample {Sample() {std::cout << "CONSTRUCTOR\n";}~Sample() {std::cout << "DESTRUCTOR\n";}
};//在接收到的指針上調(diào)用delte[]的函數(shù)
void deleter(Sample* x) {std::cout << "DELETER FUNCTION CALLED\n";delete[] x;
}int main() {//使用定制的deleter創(chuàng)建shared_ptrstd::shared_ptr<Sample> p3(new Sample[12], deleter);return 0;
}
輸出:
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
DELETER FUNCTION CALLED
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR