How can I connect boost :: shared_ptr (or other smart pointer) to the counter counter of the parent object?
I remember seeing this concept before, but I can't find it on Google now.
If I have an object of type A that directly inserts an object of type B:
class A {
B b;
};
How can I use a smart pointer to B
, e. g boost::shared_ptr<B>
, but use a reference count A
? Let's assume an instance A
itself is heap allocated. I can safely get his total score, using, say, enable_shared_from_this
.
a source to share
D'o!
Found it correctly in the documentation shared_ptr
. It's called aliasing (see section III of the shared_ptr enhancements for C ++ 0x ).
I just needed to use a different constructor (or a corresponding function reset
):
template<class Y> shared_ptr( shared_ptr<Y> const & r, T * p );
Which works like this (you need to create a shared_ptr for the parent first):
#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;
}
a source to share
I haven't tested this, but you should use a custom delaocator object to keep the shared_ptr on the parent environment as long as the child is still needed. Something like this:
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 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));
a source to share