[boost-2] 智能指针

boost库学习;

 

智能指针;

shared_ptr指针,定义在boost::shared_ptr,如果开发环境支持的话,可以使用memory中的std::shared_ptr

shared_ptr可以共享对象的所有权,而scoped_ptr是独占一个对象的。

 

因为前者保证,当引用对象的最有一个智能指针被销毁后,对象才会被释放。

因为所有权可以共享,任何一个共享指针都可以被复制,与scoped_ptr不同的是,shared_ptr可以存储在标准容器中了。

 

//===========

int main() {
    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)));
    for(auto i:v){
        cout<<*i<<endl;
    }
}

//=========

默认情况下,boost::shared_ptr 使用 delete 操作符来销毁所含的对象。 然而,具体通过什么方法来销毁,是可以指定的。

 

 

 

共享数组的行为类似于共享指针。 关键不同在于共享数组在析构时,默认使用 delete[] 操作符来释放所含的对象。 因为这个操作符只能用于数组对象,共享数组必须通过动态分配的数组的地址来初始化。

共享数组对应的类型是 boost::shared_array,它的定义在 boost/shared_array.hpp 里。

#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; 

  std::cout << i2[0] << std::endl; 

} 

就像共享指针那样,所含对象的所有权可以跟其他共享数组来共享。 这个例子中定义了2个变量 i1 和 i2,它们引用到同一个动态分配的数组。i1 通过operator[]() 操作符保存了一个整数1——这个整数可以被 i2 引用,比如打印到标准输出。

和本章中所有的智能指针一样,boost::shared_array 也同样提供了 get() 和 reset() 方法。 另外还重载了 operator bool()。

===========

shared_ptr和weaker_ptr的用法对比结果;

//=============

#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <boost/function.hpp>
#include <cstdlib>
#include <cstring>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
using namespace std;
void* reset(void *p){
    boost::shared_ptr<int> *sh = static_cast<boost::shared_ptr<int>*>(p);
    sh->reset();
}

void* print(void *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;
    }else{
        std::cout<<"has been reseted."<<endl;
    }
}

int main() {
    boost::shared_ptr<int> sh(new int(100));
    boost::weak_ptr<int> w(sh);
    pthread_t th[2];
    pthread_create(&th[0],NULL,&reset,&sh);
    pthread_create(&th[1],NULL,&print,&w);
    pthread_join(th[0],NULL);
    pthread_join(th[1],NULL);
    return 0;
}

//========

 

boost::weak_ptr 必定总是通过 boost::shared_ptr 来初始化的。一旦初始化之后,它基本上只提供一个有用的方法: lock()。此方法返回的boost::shared_ptr 与用来初始化弱指针的共享指针共享所有权。 如果这个共享指针不含有任何对象,返回的共享指针也将是空的。

当函数需要一个由共享指针所管理的对象,而这个对象的生存期又不依赖于这个函数时,就可以使用弱指针。 只要程序中还有一个共享指针掌管着这个对象,函数就可以使用该对象。 如果共享指针复位了,就算函数里能得到一个共享指针,对象也不存在了。

上例的 main() 函数中,使用pthread_create创建了2个线程。 

第一个线程函数 reset() 的参数是一个共享指针的地址。 第二个线程函数 print() 的参数是一个弱指针的地址。 这个弱指针是之前通过共享指针初始化的。

一旦程序启动之后,reset() 和 print() 就都开始执行了。 不过执行顺序是不确定的。 这就导致了一个潜在的问题:reset() 线程在销毁对象的时候print() 线程可能正在访问它。

通过调用弱指针的 lock() 函数可以解决这个问题:如果对象存在,那么 lock() 函数返回的共享指针指向这个合法的对象。否则,返回的共享指针被设置为0,这等价于标准的null指针。

弱指针本身对于对象的生存期没有任何影响。 lock() 返回一个共享指针,print() 函数就可以安全的访问对象了。 这就保证了——即使另一个线程要释放对象——由于我们有返回的共享指针,对象依然存在。


 

 

原文地址:https://www.cnblogs.com/li-daphne/p/7589628.html