Namespaces
Variants
Views
Actions

std::make_shared

From cppreference.com
< cpp‎ | memory‎ | shared ptr
Revision as of 07:41, 2 August 2017 by Cubbi (Talk | contribs)

 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
 
Dynamic memory management
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Allocators
Garbage collection support
(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... 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)
(T is U[])
template<class T>
shared_ptr<T> make_shared();
(3) (since C++20)
(T is U[N])
template<class T>
shared_ptr<T> make_shared(std::size_t N, const std::remove_extent_t<T>& u);
(4) (since C++20)
(T is U[])
template<class T> shared_ptr<T>
make_shared(const std::remove_extent_t<T>& u);
(5) (since C++20)
(T is U[N])
1) Constructs an object of type T and wraps it in a std::shared_ptr using args as the parameter list for the constructor of T. The object is constructed as if by the expression ::new (pv) T(std::forward<Args>(args)...), where pv is an internal void* pointer to storage suitable to hold an object of type T. The storage is typically larger than sizeof(T) in order to use one allocation for both the control block of the shared pointer and the T object. The std::shared_ptr constructor called by this function enables shared_from_this with a pointer to the newly constructed object of type T. This overload participates in overload resolution only if T is not an array type
2,3) Same as (1), but the element constructed is an array whose every element is default-initialized as if by placement-new expression ::new(pv) U(). The overload (2) creates the array of size N. The array elements are initialized in ascending order of their addresses.
4,5) Same, but every element of the new array is initialized from the default value u, as if by the same placement-new expression as in (1). The overload (4) creates the array of size N. The array elements are initialized in ascending order of their addresses.


Contents

Parameters

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

Return value

std::shared_ptr of an instance of type T.

Exceptions

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

Notes

This function may be used as an alternative to std::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 object T and one for the control block of the shared pointer), while std::make_shared<T> typically performs only one allocation (the standard recommends, but does not require this, all known implementations do this)
  • If any std::weak_ptr references the control block created by std::make_shared after the lifetime of all shared owners ended, the memory occupied by T persists until all weak owners get destroyed as well, which may be undesirable if sizeof(T) is large.
  • std::shared_ptr<T>(new T(args...)) may call a non-public constructor of T if executed in context where it is accessible, while std::make_shared requires public access to the selected constructor.
  • Unlike the std::shared_ptr constructors, std::make_shared does not allow a custom deleter.
(until C++20)
  • code such as f(std::shared_ptr<int>(new int(42)), g()) can cause a memory leak if g gets called after new int(42) and throws an exception, while f(std::make_shared<int>(42), g()) is safe, since two function calls are never interleaved.
(until C++17)

A constructor enables shared_from_this with a pointer ptr of type U* means that it determines if U has an unambiguous and accessible(since C++17) base class that is a specialization of std::enable_shared_from_this, and if so, the constructor evaluates if (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 the weak_this is not atomic and conflicts with any potentially concurrent access to the same object. This ensures that future calls to shared_from_this() would share ownership with the std::shared_ptr created by this raw pointer constructor.

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

Example

#include <iostream>
#include <memory>
 
void foo(const std::shared_ptr<int>& i)
{
    (*i)++;
}
 
int main()
{
    auto sp = std::make_shared<int>(12);
    foo(sp);
    std::cout << *sp << std::endl;
}

Output:

13

See also

constructs new shared_ptr
(public member function) [edit]
creates a shared pointer that manages a new object allocated using an allocator
(function template) [edit]
creates a unique pointer that manages a new object
(function template) [edit]