标签:c++ boost 智能指针 共享指针 shared_ptr
shared_ptr学习 |
#include "boost/shared_ptr.hpp"
#include <cassert>
class A {
boost::shared_ptr<int> no_;
public:
A(boost::shared_ptr<int> no) : no_(no) {}
void value(int i) {
*no_=i;
}
};
class B {
boost::shared_ptr<int> no_;
public:
B(boost::shared_ptr<int> no) : no_(no) {}
int value() const {
return *no_;
}
};
int main() {
boost::shared_ptr<int> temp(new int(14));
A a(temp);
B b(temp);
a.value(28);
assert(b.value()==28);
}#include <boost/shared_ptr.hpp>
#include <vector>
#include <iostream>
class A {
public:
virtual void sing()=0;
protected:
virtual ~A() {};
};
class B : public A {
public:
virtual void sing() {
std::cout << "Do re mi fa so la";
}
};
boost::shared_ptr<A> createA() {
boost::shared_ptr<A> p(new B());
return p;
}
int main() {
typedef std::vector<boost::shared_ptr<A> > container_type;
typedef container_type::iterator iterator;
container_type container;
for (int i=0;i<10;++i) {
container.push_back(createA());
}
std::cout << "The choir is gathered: /n";
iterator end=container.end();
for (iterator it=container.begin();it!=end;++it) {
(*it)->sing();
}
}这里有两个类, A 和 B, 各有一个虚拟成员函数 sing. B 从 A公有继承而来,并且如你所见,工厂函数 createA 返回一个动态分配的B的实例,包装在shared_ptr<A>里。在 main里, 一个包含shared_ptr<A>的 std::vector 被放入10个元素,最后对每个元素调用sing。如果我们用裸指针作为元素,那些对象需要被手工删除。而在这个例子里,删除是自动的,因为在vector的生存期中,每个shared_ptr的引用计数都保持为1;当 vector
被销毁,所有引用计数器都将变为零,所有对象都被删除。有趣的是,即使 A 的析构函数没有声明为 virtual, shared_ptr 也会正确调用 B的析构函数!class FileCloser {
public:
void operator()(FILE* file) {
std::cout << "The FileCloser has been called with a FILE*, "
"which will now be closed./n";
if (file!=0)
fclose(file);
}
};这是一个函数对象,我们用它来确保在资源要释放时调用 fclose 。下面是使用FileCloser类的示例程序。int main() {
std::cout <<
"shared_ptr example with a custom deallocator./n";
{
FILE* f=fopen("test.txt","r");
if (f==0) {
std::cout << "Unable to open file/n";
throw "Unable to open file";
}
boost::shared_ptr<FILE> my_shared_file(f, FileCloser());
// 定位文件指针
fseek(my_shared_file.get(),42,SEEK_SET);
}
std::cout << "By now, the FILE has been closed!/n";
}{
FILE* f=fopen("test.txt","r");
if (f==0) {
std::cout << "Unable to open file/n";
throw file_exception();
}
boost::shared_ptr<FILE> my_shared_file(f,&fclose);
// 定位文件指针
fseek(&*my_shared_file,42,SEEK_SET);
}
std::cout << "By now, the FILE* has been closed!/n";定制删除器在处理需要特殊释放程序的资源时非常有用。由于删除器不是 shared_ptr 类型的一部分,所以使用者不需要知道关于智能指针所拥有的资源的任何信息(当然除了如何使用它!)。例如,你可以使用对象池,定制删除器只需简单地把对象返还到池中。或者,一个 singleton 对象应该使用一个什么都不做的删除器。#include <boost/shared_ptr.hpp>
#include <iostream>
class A {
class deleter {
public:
void operator()(A* p) {
delete p;
}
};
friend class deleter;
public:
virtual void sing() {
std::cout << "Lalalalalalalalalalala";
}
static boost::shared_ptr<A> createA() {
boost::shared_ptr<A> p(new A(),A::deleter());
return p;
}
protected:
virtual ~A() {};
};
int main() {
boost::shared_ptr<A> p=A::createA();
}#include "boost/shared_ptr.hpp"
#include "boost/enable_shared_from_this.hpp"
class A;
void do_stuff(boost::shared_ptr<A> p) {
...
}
class A : public boost::enable_shared_from_this<A> {
public:
void call_do_stuff() {
do_stuff(shared_from_this());
}
};
int main() {
boost::shared_ptr<A> p(new A());
p->call_do_stuff();
}这个例子还示范了你要用shared_ptr管理this的情形。类 A 有一个成员函数 call_do_stuff 需要调用一个普通函数 do_stuff, 这个普通函数需要一个类型为 boost:: shared_ptr<A>的参数。现在,在 A::call_do_stuff里, this 不过是一个 A指针, 但由于 A 派生自 enable_shared_from_this, 调用 shared_from_this 将返回我们所要的 shared_ptr 。在enable_shared_from_this的成员函数
shared_from_this里,内部存储的 weak_ptr 被转换为 shared_ptr, 从而增加了相应的引用计数,以确保相应的对象不会被删除。
shared_ptr陷阱 |
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
using namespace std;
using boost::shared_ptr;
using boost::weak_ptr;
class B;
class A;
class A
{
public:
A(){cout << "A constructor~~" << endl;}
shared_ptr<B> m_b;
~A(){cout << "A deconstructor~~" << endl;}
};
class B
{
public:
B(){cout << "B constructor~~" << endl;}
shared_ptr<A> m_a;
~B(){cout << "B deconstructor~~" << endl;}
};
class WA;
class WB;
class WA
{
public:
WA(){cout << "WA constructor~~" << endl;}
weak_ptr<WB> m_b;
~WA(){cout << "WA deconstructor~~" << endl;}
};
class WB
{
public:
WB(){cout << "WB constructor~~" << endl;}
weak_ptr<WA> m_a;
~WB(){cout << "WB deconstructor~~" << endl;}
};
int main()
{
do
{
shared_ptr<A> aptr(new A);
shared_ptr<B> bptr(new B);
aptr->m_b = bptr;
bptr->m_a = aptr;
}while(0);
do
{
shared_ptr<WA> waptr(new WA);
shared_ptr<WB> wbptr(new WB);
waptr->m_b = wbptr;
wbptr->m_a = waptr;
}while(0);
}执行结果:
weak_ptr |
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
using std::cout;
using std::endl;
using boost::shared_ptr;
using boost::weak_ptr;
using boost::thread;
void resetobj(shared_ptr<int> *sptr)
{
sptr->reset();
return;
}
void printobj(weak_ptr<int> *wptr)
{
shared_ptr<int> sh = wptr->lock();
if(sh != NULL)
cout << "weak ptr get contens: " << *sh << endl;
else
cout << "weak ptr get empty contents." << endl;
return;
}
int main()
{
shared_ptr<int> sh(new int(99));
weak_ptr<int> w(sh);
thread sthobj(bind(resetobj, &sh));
thread wthobj(bind(printobj, &w));
sthobj.join();
wthobj.join();
cout << "finished~~~" << endl;
}执行结果:由于线程执行顺序的不确定性,printobj的打印信息不确定。namespace boost {
template<typename T> class weak_ptr {
public:
template <typename Y>
weak_ptr(const shared_ptr<Y>& r);
weak_ptr(const weak_ptr& r);
~weak_ptr();
T* get() const;
bool expired() const;
shared_ptr<T> lock() const;
};
}#include <boost/weak_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <cassert>
using boost::weak_ptr;
using boost::shared_ptr;
class A{};
int main()
{
weak_ptr<A> w;
assert((w.expired()));
{
shared_ptr<A> p(new A);
assert(p.use_count() == 1);
w = p;
assert(p.use_count() == w.use_count());
assert(p.use_count() == 1);
shared_ptr<A> p2(w);
assert(p2 == p);
assert(p.use_count() == 2);
}
assert(w.expired());
shared_ptr<A> p3 = w.lock();
assert(p3 == NULL);
}weak_ptr w 被缺省构造,意味着它初始时不旁观任何资源。要检测一个 weak_ptr 是否在旁观一个活的对象,你可以使用函数 expired. 要开始旁观,weak_ptr 必须要被赋值一个 shared_ptr. 本例中,shared_ptr p 被赋值给 weak_ptr w, 这等于说p 和 w 的引用计数应该是相同的。然后,再从weak_ptr构造一个shared_ptr,这是一种从weak_ptr那里获得对共享资源的访问权的方法。如果在构造shared_ptr时,weak_ptr
已经过期了,将从shared_ptr的构造函数里抛出一个 boost::bad_weak_ptr 类型的异常。再继续,当 shared_ptr p 离开作用域,w 就变成过期的了。当调用它的成员函数 lock 来获得一个shared_ptr时,这是另一种获得对共享资源访问权的方法,将返回一个空的 shared_ptr 。注意,从这个程序的开始到结束,weak_ptr 都没有影响到共享对象的引用计数的值。#include <boost/weak_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
using boost::weak_ptr;
using boost::shared_ptr;
using std::unary_function;
using std::equal_to;
using std::vector;
using std::string;
using std::cout;
using std::endl;
template <typename Func, typename T>
struct weak_ptr_unary_t : public unary_function<weak_ptr<T>, bool>
{
T m_t;
Func m_func;
weak_ptr_unary_t(const Func& func, const T& t):m_t(t), m_func(func){}
bool operator()(weak_ptr<T> arg)const
{
shared_ptr<T> sp = arg.lock();
if(sp == NULL)
return false;
else
return m_func(*sp, m_t);
}
};
template <typename Func, typename T>
weak_ptr_unary_t<Func, T> weak_ptr_unary(const Func& func, const T& value)
{
return weak_ptr_unary_t<Func, T>(func, value);
}
int main()
{
vector< weak_ptr<string> > vec;
shared_ptr<string> sp1(new string("An example"));
shared_ptr<string> sp2(new string("of using"));
shared_ptr<string> sp3(new string("smart pointers and predicates"));
vec.push_back(weak_ptr<string>(sp1));
vec.push_back(weak_ptr<string>(sp2));
vec.push_back(weak_ptr<string>(sp3));
vector< weak_ptr<string> > :: iterator it = find_if(vec.begin(), vec.end(), weak_ptr_unary(equal_to<string>(), string("of using")));
if(it != vec.end())
{
shared_ptr<string> sp(*it++);
cout << "find : " << *sp << endl;
}
it = find_if(vec.begin(), vec.end(), not1(weak_ptr_unary(equal_to<string>(), string("of using"))));
if(it != vec.end())
{
shared_ptr<string> sp(*it++);
cout << "the first not equal : " << *sp << endl;
}
}执行结果:标签:c++ boost 智能指针 共享指针 shared_ptr
原文地址:http://blog.csdn.net/pngynghay/article/details/43266281