您的位置:首页 > 其它

[boost-2] 智能指针

2017-09-25 01:07 260 查看
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个变量 i1i2,它们引用到同一个动态分配的数组。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() 函数就可以安全的访问对象了。 这就保证了——即使另一个线程要释放对象——由于我们有返回的共享指针,对象依然存在。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: