我记得以前遇到过这个概念,但现在在谷歌上找不到。
如果我有一个 A 类型的对象,它直接嵌入了 B 类型的对象:
class A {
B b;
};
我怎样才能有一个智能指针B
,例如boost::shared_ptr<B>
,但使用引用计数A
?假设它自己的一个实例A
是堆分配的,我可以安全地使用enable_shared_from_this
.
我记得以前遇到过这个概念,但现在在谷歌上找不到。
如果我有一个 A 类型的对象,它直接嵌入了 B 类型的对象:
class A {
B b;
};
我怎样才能有一个智能指针B
,例如boost::shared_ptr<B>
,但使用引用计数A
?假设它自己的一个实例A
是堆分配的,我可以安全地使用enable_shared_from_this
.
哦!
shared_ptr
在文档中找到它。它被称为别名(参见shared_ptr 对 C++0x 的改进的第三部分)。
我只需要使用不同的构造函数(或相应的reset
函数重载):
template<class Y> shared_ptr( shared_ptr<Y> const & r, T * p );
像这样工作(您需要先将 shared_ptr 构造为父级):
#include <boost/shared_ptr.hpp>
#include <iostream>
struct A {
A() : i_(13) {}
int i_;
};
struct B {
A a_;
~B() { std::cout << "B deleted" << std::endl; }
};
int
main() {
boost::shared_ptr<A> a;
{
boost::shared_ptr<B> b(new B);
a = boost::shared_ptr<A>(b, &b->a_);
std::cout << "ref count = " << a.use_count() << std::endl;
}
std::cout << "ref count = " << a.use_count() << std::endl;
std::cout << a->i_ << std::endl;
}
我没有对此进行测试,但是只要仍然需要子项,您就应该能够使用自定义释放器对象将 shared_ptr 保留给父项。这些方面的东西:
template<typename Parent, typename Child>
class Guard {
private:
boost::shared_ptr<Parent> *parent;
public:
explicit Guard(const boost::shared_ptr<Parent> a_parent) {
// Save one shared_ptr to parent (in this guard object and all it's copies)
// This keeps the parent alive.
parent = new boost::shared_ptr<Parent>(a_parent);
}
void operator()(Child *child) {
// The smart pointer says to "delete" the child, so delete the shared_ptr
// to parent. As far as we are concerned, the parent can die now.
delete parent;
}
};
// ...
boost::shared_ptr<A> par;
boost::shared_ptr<B> ch(&par->b, Guard<A, B>(par));