shared_ptr:
template <class Y> explicit shared_ptr(const weak_ptr<Y>& r);
从一个weak_ptr (本章稍后会介绍)构造shared_ptr。这使得weak_ptr的使用具有线程安全性,因为指向weak_ptr参数的共享资源的引用计数将会自增(weak_ptr不影响共享资源的引用计数)。如果weak_ptr为空 (r.use_count()==0), shared_ptr 抛出一个类型为bad_weak_ptr的异常。template <typename Y> shared_ptr(std::auto_ptr<Y>& r);
这个构造函数从一个auto_ptr获取r中保存的指针的所有权,方法是保存指针的一份拷贝并对auto_ptr调用release。构造后的引用计数为1。而r当然就变为空的。如果引用计数器不能分配成功,则抛出 std::bad_alloc 。
使用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);
}
类 A 和 B都保存了一个 shared_ptr<int>. 在创建A 和B的实例时,shared_ptr temp 被传送到它们的构造函数。这意味着共有三个shared_ptr:a,b, 和temp,它们都引向同一个int实例。如果我们用指针来实现对一个的共享,A 和B 必须能够在某个时间指出这个int要被删除。在这个例子中,直到main的结束,引用计数为3,当所有shared_ptr离开了作用域,计数将达到0,而最后一个智能指针将负责删除共享的int.
使用定制删除器的安全性
我们已经看到对基类使用 protected 析构函数有助于增加使用shared_ptr的类的安全性。另一个达到同样安全级别的方法是,声明析构函数为 protected (或 private) 并使用一个定制删除器来负责销毁对象。这个定制删除器必须是它要删除的类的友元,这样它才可以工作。封装这个删除器的好方法是把它实现为私有的嵌套类,如下例所示:
#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();
}
注意,我们在这里不能使用普通函数来作为 shared_ptr<A> 的工厂函数,因为嵌套的删除器是A私有的。使用这个方法,用户不可能在栈上创建A的对象,也不可能对A的指针调用delete 。
从this创建shared_ptr
有时候,需要从this获得 shared_ptr ,即是说,你希望你的类被shared_ptr所管理,你需要把"自身"转换为shared_ptr的方法。看起来不可能?好的,解决方案来自于我们即将讨论的另一个智能指针boost::weak_ptr.weak_ptr 是 shared_ptr的一个观察者;它只是安静地坐着并看着它们,但不会影响引用计数。通过存储一个指向this的weak_ptr 作为类的成员,就可以在需要的时候获得一个指向this的shared_ptr。为了你可以不必编写代码来保存一个指向this的weak_ptr,接着又从weak_ptr获shared_ptr得,Boost.Smart_ptr 为这个任务提供了一个助手类,称为enable_shared_from_this. 只要简单地让你的类公有地派生自enable_shared_from_this,然后在需要访问管理this的shared_ptr时,使用函数shared_from_this 就行了。下面的例子示范了如何使用enable_shared_from_this :
#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 :
-
当有多个使用者使用同一个对象,而没有一个明显的拥有者时
-
当要把指针存入标准库容器时
-
当要传送对象到库或从库获取对象,而没有明确的所有权时
-
当管理一些需要特殊清除方式的资源时
本文深入探讨了C++中的shared_ptr智能指针,包括其构造函数、应用场景及如何使用定制删除器提高安全性。此外,还介绍了如何从this创建shared_ptr,以便更好地管理类实例。
shared_ptr&spm=1001.2101.3001.5002&articleId=8824795&d=1&t=3&u=476f0cc0f4aa4ef6a467a50004383ed9)
6354

被折叠的 条评论
为什么被折叠?



