2012-07-02 22 views
12

मैं इस वर्गअजीब व्यवहार 2010

#include <memory> 

class ContainerUnique 
{ 
public: 

    ContainerUnique(void); 
    ~ContainerUnique(void); 

private: 
    std::unique_ptr<UniqueElement> u; 
}; 

कहाँ UniqueElement एक पॉड वर्ग कहीं परिभाषित किया गया है लेखन की कोशिश की। अब मैं इस तरह के कन्स्ट्रक्टर बॉडी को परिभाषित करता हूं:

ContainerUnique::ContainerUnique(void) 
{ 
    auto tmp = new UniqueElement(1); 

    this->u(tmp); // u is a unique_ptr<UniqueElement>. Should this call compile? 
} 

और यह अपवादों का अनुपालन करता है। प्रोग्राम चलाते हुए मुझे लगता है कि ContainerUnique के निर्माता के बाद, u में एक शून्य सूचक शामिल है।

क्या यह इरादा व्यवहार है? और मैं वास्तव में क्या अनन्य_पीटीआर विधि बुला रहा हूँ?

+3

आपके सामने आने वाली समस्याओं के बारे में निश्चित नहीं है। लेकिन कन्स्ट्रक्टर की प्रारंभिक सूची में सदस्य चर को प्रारंभ करके उनसे बचें। –

+0

हां, यही वह समाधान है जिसका मैंने अपने वास्तविक कोड में उपयोग किया था, लेकिन मुझे अभी भी इस बारे में निश्चित नहीं है कि उदाहरण में क्या हो रहा है। –

+0

अपने ऑटो चर के प्रकार को प्रिंट करने का प्रयास करें। निश्चित नहीं है कि टाइपिड काम करता है। एक बार जब आप इस प्रकार को जानते हैं तो बाकी आसान होना चाहिए। –

उत्तर

19

This is a known problem with VS2010's unique_ptr. किया जाना चाहिए यह अपने Deleter से सार्वजनिक रूप से संभालते हैं यह एक अनुकूलन (खाली आधार अनुकूलन) के रूप में खाली है। सार्वजनिक विरासत का नकारात्मक पक्ष यह है कि डिलीटर के सभी सदस्य unique_ptr के सदस्य भी उपलब्ध हो जाते हैं, इस मामले में operator()(T*) जो सूचक को हटा देता है।

बग VS2012 की लाइब्रेरी में तय किया गया है जहां विरासत निजी में बदल दी गई है।

+1

आह, आपने मुझे इसे हराया। अच्छा खोज – stijn

2

ऐसा लगता है कि

ContainerUnique::ContainerUnique(void):u(new UniqueElement(1)) { 
} 
+1

इस तरह मैंने अपने उत्पादन कोड में समस्या हल की है, लेकिन मैं अभी भी इस बारे में अनिश्चित हूं कि उदाहरण में क्या हो रहा है। –

8

आप default_delete<UniqueElement>::operator() (UniqueElement* ptr) पर कॉल कर रहे हैं, क्योंकि uniqe_ptr इससे निकलता है (खाली बेस क्लास ऑप्टिमाइज़ेशन से लाभ प्राप्त करने के लिए), और यह ptr हटा देता है। यह आपके लिए बिल्कुल सही व्यवहार नहीं है, हालांकि मुझे नहीं लगता कि मानक इसे रोकता है।