2012-12-29 3 views
16

this code을 고려std :: make_shared()는 사용자 정의 할당자를 사용합니까?

Custom new 
SomeClass() 

Another one... 

SomeClass() 

Done! 

~SomeClass() 
~SomeClass() 
Custom delete 

은 분명히 std::make_shared()new 연산자를 호출하지 않았다 - 그것은 사용자 정의 할당을 사용하고 :

#include <memory> 
#include <iostream> 


class SomeClass { 
public: 
    SomeClass() { 
     std::cout << "SomeClass()" << std::endl; 
    } 

    ~SomeClass() { 
     std::cout << "~SomeClass()" << std::endl; 
    } 

    void* operator new(std::size_t size) { 
     std::cout << "Custom new" << std::endl; 
     return ::operator new(size); 
    } 

    void operator delete(void* ptr, std::size_t size) { 
     std::cout << "Custom delete" << std::endl; 
     ::operator delete(ptr); 
    } 
}; 



int main() { 
    std::shared_ptr<SomeClass> ptr1(new SomeClass); 
    std::cout << std::endl << "Another one..." << std::endl << std::endl; 
    std::shared_ptr<SomeClass> ptr2(std::make_shared<SomeClass>()); 
    std::cout << std::endl << "Done!" << std::endl << std::endl; 
} 

여기에 출력한다. 이것이 std::make_shared()의 표준 동작입니까?

답변

16

예, 이것은 일반적인 동작입니다. 표준과 (§20.7.2.2.6 shared_ptr을 생성)

효과 : 타입 T의 목적에 적합하고, 새로운 배치 식을 통해 그 메모리에서 객체를 구성 메모리를 할당 ::new (pv) T(std::forward<Args>(args)...).

이렇게하면 make_shared이 효율성상의 이유로 단일 할당으로 공유 포인터 자체 ("제어 블록")에 대한 개체 및 데이터 구조 모두에 대한 저장소를 할당 할 수 있습니다.

해당 저장 영역 할당을 제어하려면 std::allocate_shared을 사용할 수 있습니다.

template<typename T> 
    struct shared_count_inplace 
    { 
    long m_count; 
    long weak_count; 
    typename std::aligned_storage<sizeof(T)>::type m_storage; 
    // ... 
    }; 

이 힙에 할당됩니다 유형은 다음과 같습니다 매트의 정답을 확장하려면

+4

'std :: allocate_shared (const A &, Args && ...)'도 언급 할 가치가 있습니다. 첫 번째 인수는'A :: allocate'를 호출하는 할당 자입니다. –

2

, make_shared은 일반적으로 shared_ptr 참조 횟수 및 초기화되지 않은 바이트 버퍼를 포함하는 객체를 할당함으로써 구현된다 , 귀하의 유형이 아니므로 유형의 new이 호출되지 않습니다. 그러면 유형은 (void*)&m_storage에 배치 new을 사용하여 생성됩니다.

관련 문제