I have a bunch of derived classes stored as shared pointers, I was wondering if there is any way of getting a weak_ptr to the object from inside the object?
I've tried using the shared_from_this() function but the problem is that since it's a derived class, when I make the base class inherit from enable_shared_from_this, when the derived class calls shared_from_this() it gets a shared_ptr of the base class not the derived class which I can't turn into a shared_ptr of the derived class
Any suggestions?
Usign CRTP you can achieve it:
#include <memory>
template<typename T>
struct B: std::enable_shared_from_this<T> {};
struct D: B<D> {};
int main() {
std::shared_ptr<B<D>> b = std::make_shared<D>();
std::shared_ptr<D> d = b->shared_from_this();
std::weak_ptr<D> w = b->shared_from_this();
}
If you want to have a common, non-template base class, you can rely on techniques like the double dispatching, as in the following example:
#include <memory>
#include <iostream>
struct D1;
struct D2;
struct S {
void doSomething(std::weak_ptr<D1> weak) { std::cout << "D1" << std::endl; }
void doSomething(std::weak_ptr<D2> weak) { std::cout << "D2" << std::endl; }
};
struct B: std::enable_shared_from_this<B> {
virtual void dispatch(S &) = 0;
};
template<typename T>
struct M: B {
void dispatch(S &s) override {
auto ptr = std::static_pointer_cast<T>(shared_from_this());
s.doSomething(ptr);
}
};
struct D1: M<D1> {};
struct D2: M<D2> {};
int main() {
std::shared_ptr<B> b = std::make_shared<D1>();
S s;
b->dispatch(s);
}
As @Torbjörn said, using the dynamic_pointer_cast<Derived>(base_ptr) fixed this problem as it allowed me to convert shared_ptr's down in inheritance, something that isn't directly allowed.
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