Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      std::make_shared,std::make_shared_for_overwrite

      From cppreference.com
      <cpp‎ |memory‎ |shared ptr
       
       
      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)
       
      std::shared_ptr
      Member functions
      Modifiers
      Observers
      (until C++20*)
      Non-member functions
      make_sharedmake_shared_for_overwrite
      (C++20)
      (until C++20)(until C++20)(until C++20)(until C++20)(until C++20)(C++20)
      functions(until C++26*)
      Helper classes
      Deduction guides(C++17)
       
      Defined in header<memory>
      template<class T,class...Args>
      shared_ptr<T> make_shared( Args&&...args);
      (1)(since C++11)
      template<class T>
      shared_ptr<T> make_shared(std::size_t N);
      (2)(since C++20)
      template<class T>
      shared_ptr<T> make_shared();
      (3)(since C++20)
      template<class T>
      shared_ptr<T> make_shared(std::size_t N,conststd::remove_extent_t<T>& u);
      (4)(since C++20)
      template<class T>
      shared_ptr<T> make_shared(conststd::remove_extent_t<T>& u);
      (5)(since C++20)
      template<class T>
      shared_ptr<T> make_shared_for_overwrite();
      (6)(since C++20)
      template<class T>
      shared_ptr<T> make_shared_for_overwrite(std::size_t N);
      (7)(since C++20)

      Allocates memory for an object and initialize the object with the supplied arguments. Returns astd::shared_ptr object managing the newly created object.

      1) The object is of typeT, and is constructed as if by::new(pv) T(std::forward<Args>(args)...), wherepv is avoid* pointer to storage suitable to hold an object of typeT. If the object is to be destroyed, it is destroyed as if bypt->~T(), wherept is a pointer to that object of typeT.

      This overload participates in overload resolution only ifT is not an array type.

      (since C++20)
      2) The object is of typestd::remove_extent_t<T>[N]. Each element has a default initial value.
      This overload participates in overload resolution only ifT is an unbounded array type.
      3) The object is of typeT. Each element has a default initial value.
      This overload participates in overload resolution only ifT is a bounded array type.
      4) The object is of typestd::remove_extent_t<T>[N]. Each element has the initial valueu.
      This overload participates in overload resolution only ifT is an unbounded array type.
      5) The object is of typeT. Each element has the initial valueu.
      This overload participates in overload resolution only ifT is a bounded array type.
      6) The object is of typeT.
      • IfT is not an array type, the object is constructed as if by::new(pv) T, wherepv is avoid* pointer to storage suitable to hold an object of typeT. If the object is to be destroyed, it is destroyed as if bypt->~T(), wherept is a pointer to that object of typeT.
      • IfT is a bounded array type, the initial value is unspecified for each element.
      This overload participates in overload resolution only ifT is not an array type or is an bounded array type.
      7) The object is of typestd::remove_extent_t<T>[N]. The initial value is unspecified for each element.
      This overload participates in overload resolution only ifT is an unbounded array type.

      Contents

      Initializing and destroying array elements

      Array elements of typeU are initialized in ascending order of their addresses.

      • IfU is not an array type, each element is constructed as if by the following expression, wherepv is avoid* pointer to storage suitable to hold an object of typeU:
      2,3)::new(pv) U()
      4,5)::new(pv) U(u)
      6,7)::new(pv) U
      • Otherwise, recursively initializes the elements of each element. For the next dimension:

      When the lifetime of the object managed by the returnstd::shared_ptr ends, or when the initialization of an array element throws an exception, the initialized elements are destroyed in the reverse order of their original construction.

      For each array element of non-array typeU to be destroyed, it is destroyed as if bypu->~U(), wherepu is a pointer to that array element of typeU.

      (since C++20)

      [edit]Parameters

      args - list of arguments with which an object ofT will be constructed
      N - array size to use
      u - the initial value to initialize every element of the array

      [edit]Return value

      std::shared_ptr to an object of typeT orstd::remove_extent_t<T>[N] ifT is an unbounded array type(since C++20).

      For the returnedstd::shared_ptrr,r.get() returns a non-null pointer andr.use_count() returns1.

      [edit]Exceptions

      May throwstd::bad_alloc or any exception thrown by the constructor ofT. If an exception is thrown, the functions have no effect. If an exception is thrown during the construction of the array, already-initialized elements are destroyed in reverse order.(since C++20)

      [edit]Notes

      These functions will typically allocate more memory thansizeof(T) to allow for internal bookkeeping structures such as reference counts.

      These functions may be used as an alternative tostd::shared_ptr<T>(new T(args...)). The trade-offs are:

      • std::shared_ptr<T>(new T(args...)) performs at least two allocations (one for the objectT and one for the control block of the shared pointer), whilestd::make_shared<T> typically performs only one allocation (the standard recommends, but does not require this; all known implementations do this).
      • If anystd::weak_ptr references the control block created bystd::make_shared after the lifetime of all shared owners ended, the memory occupied byT persists until all weak owners get destroyed as well, which may be undesirable ifsizeof(T) is large.
      • std::shared_ptr<T>(new T(args...)) may call a non-public constructor ofT if executed in context where it is accessible, whilestd::make_shared requires public access to the selected constructor.
      • Unlike thestd::shared_ptr constructors,std::make_shared does not allow a custom deleter.
      • std::make_shared uses::new, so if any special behavior has been set up using a class-specificoperator new, it will differ fromstd::shared_ptr<T>(new T(args...)).
      (until C++20)
      • code such asf(std::shared_ptr<int>(newint(42)), g()) can cause a memory leak ifg gets called afternewint(42) and throws an exception, whilef(std::make_shared<int>(42), g()) is safe, since two function calls arenever interleaved.
      (until C++17)

      A constructorenablesshared_from_this with a pointerptr of typeU* means that it determines ifU has anunambiguous and accessible(since C++17) base class that is a specialization ofstd::enable_shared_from_this, and if so, the constructor evaluatesif(ptr!= nullptr&& ptr->weak_this .expired())
          ptr->weak_this =std::shared_ptr<std::remove_cv_t<U>>
              (*this,const_cast<std::remove_cv_t<U>*>(ptr));
      .

      The assignment to theweak_this is not atomic and conflicts with any potentially concurrent access to the same object. This ensures that future calls toshared_from_this() would share ownership with thestd::shared_ptr created by this raw pointer constructor.

      The testptr->weak_this .expired() in the code above makes sure thatweak_this is not reassigned if it already indicates an owner. This test is required as of C++17.

      Feature-test macroValueStdFeature
      __cpp_lib_shared_ptr_arrays201707L(C++20)Array support ofstd::make_shared; overloads(2-5)
      __cpp_lib_smart_ptr_for_overwrite202002L(C++20)Smart pointer creation with default initialization (std::allocate_shared_for_overwrite,std::make_shared_for_overwrite,std::make_unique_for_overwrite); overloads(6,7)

      [edit]Example

      Run this code
      #include <iostream>#include <memory>#include <type_traits>#include <vector> struct C{// constructors needed (until C++20)    C(int i): i(i){}    C(int i,float f): i(i), f(f){}int i;float f{};}; int main(){// using “auto” for the type of “sp1”auto sp1= std::make_shared<C>(1);// overload (1)    static_assert(std::is_same_v<decltype(sp1),std::shared_ptr<C>>);std::cout<<"sp1->{ i:"<< sp1->i<<", f:"<< sp1->f<<" }\n"; // being explicit with the type of “sp2”std::shared_ptr<C> sp2= std::make_shared<C>(2,3.0f);// overload (1)    static_assert(std::is_same_v<decltype(sp2),std::shared_ptr<C>>);    static_assert(std::is_same_v<decltype(sp1), decltype(sp2)>);std::cout<<"sp2->{ i:"<< sp2->i<<", f:"<< sp2->f<<" }\n"; // shared_ptr to a value-initialized float[64]; overload (2):std::shared_ptr<float[]> sp3= std::make_shared<float[]>(64); // shared_ptr to a value-initialized long[5][3][4]; overload (2):std::shared_ptr<long[][3][4]> sp4= std::make_shared<long[][3][4]>(5); // shared_ptr to a value-initialized short[128]; overload (3):std::shared_ptr<short[128]> sp5= std::make_shared<short[128]>(); // shared_ptr to a value-initialized int[7][6][5]; overload (3):std::shared_ptr<int[7][6][5]> sp6= std::make_shared<int[7][6][5]>(); // shared_ptr to a double[256], where each element is 2.0; overload (4):std::shared_ptr<double[]> sp7= std::make_shared<double[]>(256,2.0); // shared_ptr to a double[7][2], where each double[2]// element is {3.0, 4.0}; overload (4):std::shared_ptr<double[][2]> sp8= std::make_shared<double[][2]>(7,{3.0,4.0}); // shared_ptr to a vector<int>[4], where each vector// has contents {5, 6}; overload (4):std::shared_ptr<std::vector<int>[]> sp9=        std::make_shared<std::vector<int>[]>(4,{5,6}); // shared_ptr to a float[512], where each element is 1.0; overload (5):std::shared_ptr<float[512]> spA= std::make_shared<float[512]>(1.0); // shared_ptr to a double[6][2], where each double[2] element// is {1.0, 2.0}; overload (5):std::shared_ptr<double[6][2]> spB= std::make_shared<double[6][2]>({1.0,2.0}); // shared_ptr to a vector<int>[4], where each vector// has contents {5, 6}; overload (5):std::shared_ptr<std::vector<int>[4]> spC=        std::make_shared<std::vector<int>[4]>({5,6});}

      Output:

      sp1->{ i:1, f:0 }sp2->{ i:2, f:3 }

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      LWG 4024C++20it was unclear how the objects constructed in
      std::make_shared_for_overwrite are destroyed
      made clear

      [edit]See also

      constructs newshared_ptr
      (public member function)[edit]
      creates a shared pointer that manages a new object allocated using an allocator
      (function template)[edit]
      allows an object to create ashared_ptr referring to itself
      (class template)[edit]
      creates a unique pointer that manages a new object
      (function template)[edit]
      allocation functions
      (function)[edit]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/memory/shared_ptr/make_shared&oldid=180552"

      [8]ページ先頭

      ©2009-2025 Movatter.jp