Boost库学习笔记01_智能指针

资料来源

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); 
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚拟内存会梦见进程调度嘛?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值