I was playing around for a bit using the shared_ptr's and enable_shared_from_this, while I run into something I don't really understand.
In my first attempt I constructed something like this:
class shared_test : std::enable_shared_from_this<shared_test> {
public:
void print(bool recursive) {
if (recursive) {
shared_from_this()->print(false);
}
std::cout << "printing" << std::endl;
}
};
Please note that this class is extending std::enable_shared_from_this privately. This apparently makes a lot of difference because executing a something like this:
int main() {
auto t(std::make_shared<shared_test>());
t->print(true);
return 0;
}
throws an bad_weak_ptr exception. Where as if I change the class definition to inherent publicly from std::enable_shared_from_this this runs just find.
Why is that, what do I miss here? And isn't there a way to make it work for private inheritance, since the 'outside world' of the shared_test class does not need to know that it is enabling shared from this... (at least, not if you ask me, or do I miss something again?)
std::enable_shared_from_this is a standard solution that enables a shared_ptr managed object to acquire a shared_ptr to itself on demand. A class T that publicly inherits an std::enable_shared_from_this<T> encapsulates a std::weak_ptr<T> to itself that can be converted to a std::shared_ptr<T> when needed.
Objects derived from enable_shared_from_this can use the shared_from_this methods in member functions to create shared_ptr owners of the instance that share ownership with existing shared_ptr owners.
Why is that, what do I miss here?
To make shared_from_this
work enable_shared_from_this
has to know about shared_ptr
which holds the class. In your STL implementation it is weak_ptr
, through other implementations are possible. When you inherit privately, then it is not possible to access base class's properties from the outside of your class. Actually it is not even possible to understand that you have inherited from. So make_shared
generates usual shared_ptr initialization without setting proper fields in enable_shared_from_this
.
Exception is thrown not from make_shared
but form shared_from_this
because enable_shared_from_this
was not initialized properly.
And isn't there a way to make it work for private inheritance, since the 'outside world' of the shared_test class does not need to know that it is enabling shared from this...
No. Outside world has to know that the object has special relations with shared_ptr to work properly with it.
isn't there a way to make it work for private inheritance, since the 'outside world' of the shared_test class does not need to know that it is enabling shared from this
shared_ptr
itself is part of the 'outside world'; the shared_ptr
constructor needs to be able to access the enable_shared_from_this
base class subobject of the shared_test
object it points to, in order to initialize the private weak_ptr
member of the enable_shared_from_this
implementation.
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