2012-12-29 33 views
16

考慮this codestd :: make_shared()使用自定義分配器嗎?

#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; 
} 

下面是它的輸出:

Custom new 
SomeClass() 

Another one... 

SomeClass() 

Done! 

~SomeClass() 
~SomeClass() 
Custom delete 

顯然,std::make_shared()沒叫new運營商 - 這是使用自定義的分配器。這是std::make_shared()的標準行爲嗎?

回答

16

是的,這是標準行爲。從標準(§20.7.2.2.6shared_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沒有被調用。然後,您的類型將使用位置new在位置(void*)&m_storage構建。

相關問題