shared_ptr_make_shared

shared_ptr_make_shared (std::make_shared)

<memory> 헤더에 정의되어 있어요. 객체를 위한 메모리를 할당하고 제공된 인자들로 객체를 초기화해 새로 만든 객체를 관리하는 std::shared_ptr을 돌려줘요. 보통 한 번만 할당해 T 객체와 제어 블록을 같은 메모리에 둬요. C++11부터 도입됐어요.

출처: cppreference

본문

template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );          // (1) since C++11, constexpr since C++26
template< class T >
shared_ptr<T> make_shared( std::size_t N );           // (2) since C++20, constexpr since C++26
template< class T >
shared_ptr<T> make_shared();                          // (3) since C++20, constexpr since C++26
template< class T >
shared_ptr<T> make_shared( std::size_t N, const std::remove_extent_t<T>& u );   // (4) since C++20
template< class T >
shared_ptr<T> make_shared( const std::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
  • (1) T 타입 객체를 ::new (pv) T(std::forward<Args>(args)...)로 구성. 비-배열 타입일 때만 참여.
  • (2) std::remove_extent_t<T>[N] 배열. 각 요소 기본 초기값. 무한 배열 타입일 때만 참여.
  • (3) T 배열, 각 요소 기본 초기값. 유한 배열 타입일 때만 참여.
  • (4)(5) 각 요소가 초기값 u를 갖는 배열 버전.
  • (6)(7) make_shared_for_overwrite. 객체를 ::new (pv) T로 기본-초기화해 덮어쓰게 내버려둠.

std::make_shared는 보통 sizeof(T)보다 더 많은 메모리를 할당해 참조 카운트 같은 내부 관리 구조를 담아요. std::shared_ptr<T>(new T(args...))의 대안으로 쓰이며, 보통 할당을 한 번만 수행해요.

trade-off

  • std::shared_ptr<T>(new T(args...))는 최소 두 번(객체 T와 제어 블록) 할당하지만, make_shared는 보통 한 번만 할당해요.
  • make_shared로 만든 제어 블록을 std::weak_ptr이 참조하면 모든 shared 소유자가 사라진 뒤에도 T가 차지하는 메모리가 모든 weak 소유자가 파괴될 때까지 유지돼요. sizeof(T)가 크면 바람직하지 않을 수 있어요.
  • make_shared는 선택된 생성자에 대한 공개 접근을 요구하고 커스텀 삭제자를 허용하지 않아요.

예제

#include <iostream>
#include <memory>
#include <type_traits>
#include <vector>

struct C
{
    C(int i) : i(i) {}
    C(int i, float f) : i(i), f(f) {}
    int i;
    float f{};
};

int main()
{
    auto sp1 = std::make_shared<C>(1); // overload (1)
    std::cout << "sp1->{ i:" << sp1->i << ", f:" << sp1->f << " }\n";

    std::shared_ptr<float[]> sp3 = std::make_shared<float[]>(64);  // (2)
    std::shared_ptr<short[128]> sp5 = std::make_shared<short[128]>();  // (3)
    std::shared_ptr<double[]> sp7 = std::make_shared<double[]>(256, 2.0);  // (4)
    std::shared_ptr<float[512]> spA = std::make_shared<float[512]>(1.0);  // (5)
}

출력:

sp1->{ i:1, f:0 }

더 알아보기 (Learn more)

cppreference