smart pointers(智能指針)是存儲“指向動態分配(在堆上)的對象的指針”的對象。他們的行爲很像 C++ 的內建指針,只是它們可以在適當的時候自動刪除它們所指向的對象。智能指針在面對異常時有非常顯著的作用,它們可以確保動態分配對象的完全析構。它們還可 以用於跟蹤多主人共享的動態分配對象。
在概念上,智能指針可以看作擁有它所指向的對象,並因此在對象不再需要時負責將它刪除。
1 scope_ptr
scoped_ptr class template類模板存儲一個指向動態分配對象的指針(動態分配對象是用 C++ new 表達式分配的)。在 scoped_ptr 的析構過程中,或者經由一個顯式的 reset,要保證它所指向的對象被刪除。Scope_ptr 所有權不能轉讓。
#include <boost/scoped_ptr.hpp>
#include <iostream>
struct Shoe
{
Shoe()
{
std::cout << "Shoe Construct\n";
}
~Shoe()
{
std::cout << "Shoe DeConstruct\n";
}
};
class MyClass
{
boost::scoped_ptr<int> ptr;
public:
MyClass() :ptr(new int)
{
*ptr = 0;
std::cout << "MyClass Construct" << std::endl;
}
int add_one()
{
return ++*ptr;
}
};
int main()
{
boost::scoped_ptr<Shoe> x(new Shoe);
MyClass my_instance;
std::cout << my_instance.add_one() << '\n';
std::cout << my_instance.add_one() << '\n';
}
2 scoped_array
類模板存儲一個指向一個動態分配數組的指針(動態分配數組是用 C++ new[] 表達式分配的)。在 scoped_array 的析構過程中,或者經由一個顯式的 reset,要保證它所指向的數組被刪除
int * arr = new int[100];
boost::scoped_array<int> sa(arr);
for(int i = 0; i < 100; i++)
{
sa[i] = i + 2;//像普通數據一樣使用
}
//程序結束時,自動使用delete[]釋放內存
3 shared_ptr
類模板存儲一個指向動態分配對象(一般是用 C++ new-expression 生成的)的指針。在最後一個 shared_ptr 所指向的對象被銷燬或重置時,要保證它所指向的對象被刪除.
shared_ptr 對象提供與內建類型一樣的線程安全級別。一個 shared_ptr 實例可以同時被多個線程“讀”(僅使用不變操作進行訪問)。不同的 shared_ptr 實例可以同時被多個線程“寫入”(使用類似 operator= 或 reset 這樣的可變操作進行訪問)(即使這些實例是拷貝,而且共享下層的引用計數)。
任何其它的同時訪問的結果會導致未定義行爲。
share_ptr 多個線程讀是安全的
class Shoe
{
public:
Shoe(){std::cout << "Shoe Construct\n";}
void Show(){std::cout << "Shoe Show \n";}
~Shoe(){std::cout << "Shoe Destructor \n";}
};
void* thread_func(void* p)
{
std::cout << "thread_func begin" << std::endl;
boost::shared_ptr<Shoe> ps = *(boost::shared_ptr<Shoe>*)(p);
ps->Show();
std::cout << "thread_func end" << std::endl;
return NULL;
}
int main()
{
boost::shared_ptr<Shoe> p (new Shoe());
boost::shared_ptr<Shoe> p2 = p;
std::cout << p.unique() << std::endl;//返回use_count() == 1
std::cout << p2.use_count() << std::endl;//use_count測試用
Shoe* pShow = p.get();//返回所存儲的指針
if(pShow != NULL)
{
pShow->Show();
}
pthread_t threadid;
int err = pthread_create(&threadid, NULL, thread_func, (void*)&p);
std::cout << "p2.show";
p2->Show();
err = pthread_join(threadid, NULL);
std::cout << "err = " << err << std::endl;
}
4 weak_ptr