2012-12-29 26 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 निर्माण):

प्रभाव: आवंटित स्मृति प्रकार टी का एक उद्देश्य के लिए उपयुक्त और प्लेसमेंट नई अभिव्यक्ति के माध्यम से है कि स्मृति में एक वस्तु का निर्माण ::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 ए और, Args && ...)' भी उल्लेखनीय है। पहला तर्क 'ए :: आवंटन' पर कॉल करने के लिए आवंटक है। –

2

चटाई का सही जवाब पर विस्तार करने के लिए, make_shared आम तौर पर एक उद्देश्य यह है कि shared_ptr संदर्भ में गिना जाता है और अप्रारंभीकृत बाइट्स की एक बफर शामिल आवंटन द्वारा कार्यान्वित किया जाता है , आपका प्रकार नहीं, इसलिए आपके प्रकार का new नहीं कहा जाता है। फिर आपके प्रकार का स्थान स्थान (void*)&m_storage पर प्लेसमेंट का उपयोग करके बनाया जाएगा।