1.1 shared_ptr作爲一個動態分配的對象,當最後一個指向其內容的指針銷燬(destroyed)或重置(reset),其指向的內容會被銷燬(deleted)。
example:
shared_ptr<double[1024]> p1( new double[1024] );
shared_ptr<double[]> p2( new double[n] );
1.2 避免使用未命名的shared_ptr臨時保存類型,例如:
void f(shared_ptr<int>, int);
int g();
void ok()
{
shared_ptr<int> p( new int(2) );
f( p, g() );
}
void bad()
{
f( shared_ptr<int>( new int(2) ), g() );
}
由於函數調用參數是無需的,有可能先執行new int(2) , 再執行 g(), 如果這是g()拋出異常,可能永遠不能執行shared_ptr的構造函數。推薦使用安全,快速的的make_shared和allocate_shared函數。(
boost/make_shared.hpp
)
1.3 常用函數
reset()
get()
unique()
swap()
等。
2. make_shared
2.1 生成shared_ptr比new更安全,更高效的方法是make_shared(使用系統默認new操作),allocate_shared(允許用戶指定allocate函數)。
2.2 跟new比較
new會有兩次內存分配,一次是生成對象( new int() ),一次是引用計數;
make_shared把兩次合併成了一次,官方說法是:它可以只用內存分配完成對象分配和相關控制塊分配,消除相當一部分創建shared_ptr的開銷(Besides convenience and style, such a function is also exception safe and considerably faster because it can use a single allocation for both the object and its corresponding control
block, eliminating a significant portion of shared_ptr
's construction overhead.)。
example:
boost::shared_ptr<std::string> x = boost::make_shared<std::string>("hello, world!");
std::cout << *x;
3. 綜合分析
#include <iostream>
#include <boost/make_shared.hpp>
#include <thread>
typedef std::function<void ()> fp;
using namespace std;
class Bar
{
public:
Bar()
{
printf ("Bar init\n");
}
void print ()
{
printf ("in the bar \n");
sleep(3);
}
};
int main()
{
std::vector<boost::shared_ptr<thread> > kafka_threads;
for (int i = 0; i < 2; ++i) {
//生成Bar類型shared_ptr,這個時候會創建了Bar對象,調用構造函數;
auto kafka_service = boost::make_shared<Bar>();
cout << "push_back thread: " << i << endl;
kafka_threads.push_back(
//生成新thread,用bind函數綁定Bar成員函數,並作爲thread的執行函數,這個時候thread已經開始運行了;
boost::make_shared<thread>(std::bind(&Bar::print, kafka_service)));
}
for (int i = 0; i < 2; ++i) {
kafka_threads[i]->join();
}
}