I need to find a solution to allow a subclass to get its proper smart pointer.
class Parent : public enable_shared_from_this {
...
}
class Child : public Parent {
public Child(){
boost::shared_ptr<Parent> pointer=shared_from_this(); // should work
boost::shared_ptr<Child> pointer=shared_from_this(); // won't work.
...
}
How do I get the right smart pointer using shared_from_this()?
CONTEXT:
I'm writing a bit of notifier/listener stuff, and some classes will naturally need to register and unregister themselves from the notifier. For example,
class Body : extends Listener<BodyMessage>{ // listen for BodyMessage messages
public:
Body() {
Notifier<BodyMessage>::register(this); // register with the appropriate notifier
}
virtual ~Body {
Notifier<BodyMessage>::unregister(this); // unregister
}
bool notify(BodyMessage m){ ... }
...
}
Normally I would just use the this pointer, and all would be well. I've gotten the Notifier to use templates, so I can pass messages only to the ones that want to hear them.
However, I want to use smart pointers. If the notifier looks like this:
template<typename t>
class Notifier {
public:
static void register<boost::shared_ptr<Listener<t>>> boost::shared_ptr<Listener<t>> listener);
...
}
then I cannot use the this pointer any more. Naturally, I made Body extend enable_shared_from_this:
class Body : public boost::enable_shared_from_this, public Listener<BodyMessage> {
public:
Notifier<BodyMessage>::register(get_shared_ptr());
...
}
And that seems to works for Bodies. It doesn't work, however, for subclasses of bodies (or, at least, it doesn't seem to):
class BodyChild : public Body {
public:
BodyChild(){
Notifier<BodyMessage>::register(get_shared_ptr());
}
likely because I can't cast a shared_pointer. SO, can I make a solution that
I'm open to other ideas, but if I can get this to work, I'll be thrilled.
You can cast smart pointers, and Boost provides you with a few templates to ease this. You have eg. static_pointer_cast
and dynamic_pointer_cast
which allow you to cast "through" the pointer.
Since this
is of the right dynamic type, you can invoke boost::static_pointer_cast
on the return value of shared_from_this()
:
boost::shared_ptr<Child> p = static_pointer_cast<Child>(shared_from_this());
(no need to qualify static_pointer_cast
thanks to Koenig lookup)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With