Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      std::enable_shared_from_this

      From cppreference.com
      <cpp‎ |memory
       
       
      Memory management library
      (exposition only*)
      Allocators
      Uninitialized memory algorithms
      Constrained uninitialized memory algorithms
      Memory resources
      Uninitialized storage(until C++20)
      (until C++20*)
      (until C++20*)
      Garbage collector support(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
       
       
      Defined in header<memory>
      template<class T>
      class enable_shared_from_this;
      (since C++11)

      std::enable_shared_from_this allows an objectt that is currently managed by astd::shared_ptr namedpt to safely generate additionalstd::shared_ptr instancespt1,pt2 etc. that all share ownership oft withpt.

      Publicly inheriting fromstd::enable_shared_from_this<T> provides the typeT with a member functionshared_from_this. If an objectt of typeT is managed by astd::shared_ptr<T> namedpt, then callingT::shared_from_this will return a newstd::shared_ptr<T> that shares ownership oft withpt.

      Contents

      [edit]Data members

      Member Description
      mutablestd::weak_ptr<T>weak_this the object tracking the control block of the first shared owner of*this
      (exposition-only member object*)

      [edit]Member functions

      constructs anenable_shared_from_this object
      (protected member function)
      destroys anenable_shared_from_this object
      (protected member function)
      returns a reference to*this
      (protected member function)
      returns astd::shared_ptr which shares ownership of*this
      (public member function)
      returns astd::weak_ptr which shares ownership of*this
      (public member function)

      [edit]Notes

      The constructors ofstd::shared_ptr detect the presence of an unambiguous and accessible (i.e. public inheritance is mandatory)enable_shared_from_this base and assign the newly createdstd::shared_ptr toweak_this if not already owned by a livestd::shared_ptr. Constructing astd::shared_ptr for an object that is already managed by anotherstd::shared_ptr will not consultweak_this and thus will lead to undefined behavior.

      It is permitted to callshared_from_this only on a previously shared object, i.e. on an object managed bystd::shared_ptr<T>. Otherwise,std::bad_weak_ptr is thrown (by thestd::shared_ptr constructor from a default-constructedweak_this ).

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

      [edit]Example

      Run this code
      #include <iostream>#include <memory> class Good:public std::enable_shared_from_this<Good>{public:std::shared_ptr<Good> getptr(){return shared_from_this();}}; class Best:public std::enable_shared_from_this<Best>{struct Private{explicit Private()=default;}; public:// Constructor is only usable by this class    Best(Private){} // Everyone else has to use this factory function// Hence all Best objects will be contained in shared_ptrstaticstd::shared_ptr<Best> create(){returnstd::make_shared<Best>(Private());} std::shared_ptr<Best> getptr(){return shared_from_this();}}; struct Bad{std::shared_ptr<Bad> getptr(){returnstd::shared_ptr<Bad>(this);}    ~Bad(){std::cout<<"Bad::~Bad() called\n";}}; void testGood(){// Good: the two shared_ptr's share the same objectstd::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 callertry{        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 cannot 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 is the only owner of the objectstd::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() = 2bad_weak_ptrbest1.use_count() = 2bad1.use_count() = 1Bad::~Bad() calledBad::~Bad() called*** glibc detected *** ./test: double free or corruption

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      LWG 2179
      (P0033R1)
      C++11given typeT derived fromenable_shared_from_this, the behavior of
      constructing twostd::shared_ptr<T>s from the sameT* object was unclear
      the behavior is
      undefined in this case
      LWG 2529
      (P0033R1)
      C++11it was unclear how the underlyingstd::weak_ptr is updatedmade clear

      [edit]See also

      (C++11)
      smart pointer with shared object ownership semantics
      (class template)[edit]
      creates a shared pointer that manages a new object
      (function template)[edit]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/memory/enable_shared_from_this&oldid=177226"

      [8]ページ先頭

      ©2009-2025 Movatter.jp