Posted Joe Chu cpp3 minutes read (About 494 words)0 visits
std::enable_shared_from_this
Safe ownership management.
1. Introduction
std::enable_shared_from_this is a standard library utility in C++ that helps manage std::shared_ptr instances. It allows an object to create a shared pointer (std::shared_ptr) that shares ownership of the object. This can be particularly useful when you want to ensure that a class instance can generate shared pointers to itself without creating multiple std::shared_ptr instances that manage the same object.
Key Features
The class that wants to use this utility should inherit from std::enable_shared_from_this<T>.
This class provides a member function shared_from_this(), which returns a std::shared_ptr to the object.
It ensures that no multiple std::shared_ptr instances try to manage the same object, preventing potential undefined behavior.
classA : public std::enable_shared_from_this<A> { public: A() { std::cout << "A constructor" << std::endl; }
~A() { std::cout << "A destructor" << std::endl; }
std::shared_ptr<A> getShared(){ // Use shared_from_this() to create a shared_ptr that shares ownership with the existing shared_ptr returnshared_from_this(); } };
intmain(){ // Create a shared_ptr to A std::shared_ptr<A> ptr1 = std::make_shared<A>();
// Create another shared_ptr using shared_from_this() std::shared_ptr<A> ptr2 = ptr1->getShared();
// Both ptr1 and ptr2 share ownership of the same object std::cout << "ptr1 use_count: " << ptr1.use_count() << std::endl; // Output: 2 std::cout << "ptr2 use_count: " << ptr2.use_count() << std::endl; // Output: 2
return0; }
A bad attempt to achieve the same thing without using std::enable_shared_from_this could be:
intmain(){ // each shared_ptr thinks it's the only owner of the object std::shared_ptr<B> b1 = std::make_shared<B>(); std::shared_ptr<B> b2 = b1->getptr(); return0; }
1 2
double free or corruption (out) Program terminated with signal: SIGSEGV
2. Example
In the observer pattern, we want observers to hold shared pointers to the same subject.