GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
std::enable_shared_from_this(3) C++ Standard Libary std::enable_shared_from_this(3)

std::enable_shared_from_this - std::enable_shared_from_this


Defined in header <memory>
template< class T > class enable_shared_from_this; (since C++11)


std::enable_shared_from_this allows an object t that is currently managed by a
std::shared_ptr named pt to safely generate additional std::shared_ptr instances
pt1, pt2, ... that all share ownership of t with pt.


Publicly inheriting from std::enable_shared_from_this<T> provides the type T with a
member function shared_from_this. If an object t of type T is managed by a
std::shared_ptr<T> named pt, then calling T::shared_from_this will return a new
std::shared_ptr<T> that shares ownership of t with pt.


constructor constructs an enable_shared_from_this object
(protected member function)
destructor destroys an enable_shared_from_this object
(protected member function)
operator= returns a reference to this
(protected member function)
shared_from_this returns a shared_ptr which shares ownership of *this
(public member function)
weak_from_this returns the weak_ptr which shares ownership of *this
(C++17) (public member function)


Member name Definition
weak_this (private)(C++17) std::weak_ptr object tracking the control block of the
first shared owner of *this. Exposition only


A common implementation for enable_shared_from_this is to hold a weak reference
(such as std::weak_ptr) to this. The constructors of std::shared_ptr detect the
presence of an
unambiguous and accessible (ie. public inheritance is mandatory)
(since C++17) enable_shared_from_this base and assign the newly created
std::shared_ptr to the internally stored weak reference
if not already owned by a live std::shared_ptr
(since C++17). Constructing a std::shared_ptr for an object that is already managed
by another std::shared_ptr will not consult the internally stored weak reference and
thus will lead to undefined behavior.


It is permitted to call shared_from_this only on a previously shared object, i.e. on
an object managed by std::shared_ptr<T>. Otherwise
the behavior is undefined
(until C++17)
std::bad_weak_ptr is thrown (by the shared_ptr constructor from a
default-constructed weak_this)
(since C++17).


enable_shared_from_this provides the safe alternative to an expression like
std::shared_ptr<T>(this), which is likely to result in this being destructed more
than once by multiple owners that are unaware of each other (see example below).


Feature-test macro: __cpp_lib_enable_shared_from_this

// Run this code


#include <memory>
#include <iostream>


struct Good : std::enable_shared_from_this<Good> // note: public inheritance
{
std::shared_ptr<Good> getptr() {
return shared_from_this();
}
};


struct Best : std::enable_shared_from_this<Best> // note: public inheritance
{
std::shared_ptr<Best> getptr() {
return shared_from_this();
}
// No public constructor, only a factory function,
// so there's no way to have getptr return nullptr.
[[nodiscard]] static std::shared_ptr<Best> create() {
// Not using std::make_shared<Best> because the c'tor is private.
return std::shared_ptr<Best>(new Best());
}
private:
Best() = default;
};


struct Bad
{
std::shared_ptr<Bad> getptr() {
return std::shared_ptr<Bad>(this);
}
~Bad() { std::cout << "Bad::~Bad() called\n"; }
};


void testGood()
{
// Good: the two shared_ptr's share the same object
std::shared_ptr<Good> good0 = std::make_shared<Good>();
std::shared_ptr<Good> good1 = good0->getptr();
std::cout << "good1.use_count() = " << good1.use_count() << '\n';
}


void misuseGood()
{
// Bad: shared_from_this is called without having std::shared_ptr owning the caller
try {
Good not_so_good;
std::shared_ptr<Good> gp1 = not_so_good.getptr();
} catch(std::bad_weak_ptr& e) {
// undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)
std::cout << e.what() << '\n';
}
}


void testBest()
{
// Best: Same but can't stack-allocate it:
std::shared_ptr<Best> best0 = Best::create();
std::shared_ptr<Best> best1 = best0->getptr();
std::cout << "best1.use_count() = " << best1.use_count() << '\n';


// Best stackBest; // <- Will not compile because Best::Best() is private.
}


void testBad()
{
// Bad, each shared_ptr thinks it's the only owner of the object
std::shared_ptr<Bad> bad0 = std::make_shared<Bad>();
std::shared_ptr<Bad> bad1 = bad0->getptr();
std::cout << "bad1.use_count() = " << bad1.use_count() << '\n';
} // UB: double-delete of Bad


int main()
{
testGood();
misuseGood();


testBest();


testBad();
}


good1.use_count() = 2
bad_weak_ptr
best1.use_count() = 2
bad1.use_count() = 1
Bad::~Bad() called
Bad::~Bad() called
*** glibc detected *** ./test: double free or corruption


shared_ptr smart pointer with shared object ownership semantics
(C++11) (class template)

2022.07.31 http://cppreference.com

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.