资料来源
http://zh.highscore.de/cpp/boost/
1.作用域指针 scoped_ptr
一个作用域指针独占一个动态分配的对象。
#include <iostream>
#include "boost/scoped_ptr.hpp"
using namespace std;
int main()
{
boost::scoped_ptr<int> a(new int);
*a = 1;
*a.get() = 2;
cout<<*a<<endl;
a.reset(new int);
return 0;
}
一经初始化,智能指针 boost::scoped_ptr 所包含的对象,可以通过类似于普通指针的接口来访问。
这是因为重载了相关的操作符 operator*(),operator->() 和 operator bool() 。
此外,还有 get() 和 reset() 方法。
前者返回所含对象的地址,后者用一个新的对象来重新初始化智能指针。
在这种情况下,新创建的对象赋值之前会先自动释放所包含的对象。
2.作用域数组scoped_array
作用域数组的使用方式与作用域指针相似。
关键不同在于,作用域数组的析构函数使用 delete[] 操作符来释放所包含的对象。
因为该操作符只能用于数组对象,所以作用域数组必须通过动态分配的数组来初始化。
#include <boost/scoped_array.hpp>
int main()
{
boost::scoped_array<int> i(new int[2]);
*i.get() = 1;
i[1] = 2;
i.reset(new int[3]);
}
3.共享指针shared_ptr【重点】
使用率最高的智能指针。
智能指针 boost::shared_ptr 基本上类似于 boost::scoped_ptr。 关键不同之处在于 boost::shared_ptr 不一定要独占一个对象。
它可以和其他 boost::shared_ptr 类型的智能指针共享所有权。
下面这个例子生动形象的展现了共享指针的特点。
#include <iostream>
using namespace std;
#include <boost/shared_ptr.hpp>
int main()
{
boost::shared_ptr<int> i1(new int(1));
cout<<"i1值="<<*i1<<endl;//i1值=1
cout<<"i1地址="<<i1<<endl;//i1地址=0000024C4EB93840
boost::shared_ptr<int> i2(i1);
cout<<"i2值="<<*i1<<endl;//i2值=1
cout<<"i2地址="<<i1<<endl;//i2地址=0000024C4EB93840
i1.reset(new int(2));
cout<<"i1值="<<*i1<<endl;//i1值=2
cout<<"i1地址="<<i1<<endl;//i1地址=0000024C4EB937A0
}
本例中定义了2个共享指针 i1 和 i2,它们都引用到同一个 int 类型的对象。
i1 通过 new 操作符返回的地址显示的初始化,i2 通过 i1 拷贝构造而来。
i1 接着调用 reset(),它所包含的整数的地址被重新初始化。不过它之前所包含的对象并没有被释放,因为 i2 仍然引用着它,所以它打印的地址仍为i1之前的地址。
智能指针 boost::shared_ptr 记录了有多少个共享指针在引用同一个对象,只有在最后一个共享指针销毁时才会释放这个对象。
故因为共享指针的特性,我们可以使用容器保存该指针,这是独占指针所做不到的。
#include <boost/shared_ptr.hpp>
#include <vector>
int main()
{
std::vector<boost::shared_ptr<int> > v;
v.push_back(boost::shared_ptr<int>(new int(1)));
v.push_back(boost::shared_ptr<int>(new int(2)));
}
多亏了有 boost::shared_ptr,我们才能像上例中展示的那样,在标准容器中安全的使用动态分配的对象。
因为 boost::shared_ptr 能够共享它所含对象的所有权,所以保存在容器中的拷贝(包括容器在需要时额外创建的拷贝)都是和原件相同的。
共享数组shared_array
同理。
#include <boost/shared_array.hpp>
#include <iostream>
int main()
{
boost::shared_array<int> i1(new int[2]);
boost::shared_array<int> i2(i1);
i1[0] = 1; //1
std::cout << i2[0] << std::endl;
}
弱指针weak_ptr
到目前为止介绍的各种智能指针都能在不同的场合下独立使用。 相反,弱指针只有在配合共享指针一起使用时才有意义。
共享指针指向的对象可以被多次引用,
但是这也引申出一个问题,
多线程中一个子线程使用reset销毁了这个对象,可是另一个线程可能正在访问它。
此时弱指针的用处就体现出来了。
boost::weak_ptr 必定总是通过 boost::shared_ptr 来初始化的。一旦初始化之后,它基本上只提供一个有用的方法: lock()。此方法返回的boost::shared_ptr 与用来初始化弱指针的共享指针共享所有权。 如果这个共享指针不含有任何对象,返回的共享指针也将是空的。
通过调用弱指针的 lock() 函数可以解决这个问题:如果对象存在,那么 lock() 函数返回的共享指针指向这个合法的对象。否则,返回的共享指针被设置为0,这等价于标准的null指针。
#include <windows.h>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <iostream>
DWORD WINAPI reset(LPVOID p)
{
boost::shared_ptr<int> *sh = static_cast<boost::shared_ptr<int>*>(p);
sh->reset();
return 0;
}
DWORD WINAPI print(LPVOID p)
{
boost::weak_ptr<int> *w = static_cast<boost::weak_ptr<int>*>(p);
boost::shared_ptr<int> sh = w->lock();
if (sh)
std::cout << *sh << std::endl;
return 0;
}
int main()
{
boost::shared_ptr<int> sh(new int(99));
boost::weak_ptr<int> w(sh);
HANDLE threads[2];
threads[0] = CreateThread(0, 0, reset, &sh, 0, 0);
threads[1] = CreateThread(0, 0, print, &w, 0, 0);
WaitForMultipleObjects(2, threads, TRUE, INFINITE);
}