Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
std::enable...d_from_this(3)  C++ Standard Libary std::enable...d_from_this(3)

NAME
       std::enable_shared_from_this - std::enable_shared_from_this

Synopsis
	  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  man-
       aged 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.

Member functions
	  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 objects
	  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

Notes
	  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 cre-
       ated
	  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  expres-
       sion 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 ex-
       ample below).

	  Feature-test macro: __cpp_lib_enable_shared_from_this

Example
       // Run this code

	#include <memory>
	#include <iostream>

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

	struct	Best  :	std::enable_shared_from_this<Best> // note: public in-
       heritance
	{
	    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  pri-
       vate.
		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();
	}

Possible output:
	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

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

http://cppreference.com		  2022.07.31	  std::enable...d_from_this(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::enable_shared_from_this&sektion=3&manpath=FreeBSD+Ports+15.0>

home | help