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