2015-09-23 15 views
5

मैं सी ++ 11 के shared_ptr का उपयोग करने के लिए एक जटिल स्मृति-प्रबंधन प्रोटोकॉल के साथ कच्चे पॉइंटर्स से मौजूदा प्रोजेक्ट को बदलने की कोशिश कर रहा एक सापेक्ष सी ++ नौसिखिया हूं। कुल मिलाकर यह बहुत आसानी से चल रहा है, और मैं सोचता हूं मैं समझता हूं कि कैसे shared_ptr चाल semantics, rvalue संदर्भ, आदि के मामले में काम करता है अच्छी चीजें।एक साझा_ptr स्वैप करने की कोशिश कर रहे अजीब त्रुटि()

हालांकि, मैंने एक अजीब त्रुटि मारा है जिसे मैं समझ नहीं पा रहा हूं और कैसे ठीक नहीं किया जाए। पहले एक छोटी सी पृष्ठभूमि। मैं एक वर्ग पदानुक्रम EidosValue नामित एक सार आधार वर्ग में निहित है, और एक वर्ग EidosValue_Int_vector नामित (परोक्ष रूप से) इस बात का एक ठोस उपवर्ग है:

class EidosValue 
class EidosValue_Int : public EidosValue 
class EidosValue_Int_vector : public EidosValue_Int 

मेरे कोड आम तौर पर EidosValue में traffics, लेकिन कभी कभी, खासकर जब एक बनाने नया मान, मुझे एक विशिष्ट उपclass को संभालने की जरूरत है।

मैं इन कक्षाओं के लिए shared_ptr रों लिए typedefs किया है, इसलिए मैं है:

typedef std::shared_ptr<EidosValue> EidosValue_SP; 
typedef std::shared_ptr<EidosValue_Int_vector> EidosValue_Int_vector_SP; 
अन्य लोगों के अलावा

। ठीक है, तो अब समस्या के मूल में। मेरे पास एक ऐसा फ़ंक्शन है जो EidosValue_SP देता है जो इसे बनाता है। फ़ंक्शन के भीतर तर्क के आधार पर, यह EidosValue के कई अलग-अलग ठोस उपखंडों में से एक बना सकता है।

EidosValue_SP MyClass::MyMethod(...) 
{ 
    EidosValue_SP result; 

    if (...) 
    { 
     EidosValue_Int_vector_SP int_result_SP = make_shared<EidosValue_Int_vector>(); 
     ... do subclass-specific stuff with int_result_SP... 
     result.swap(int_result_SP); 
    } 
    else (...) 
    { 
     ...similar logic for other subclasses... 
    } 

    ...other shared logic... 
    return result; 
} 

समस्या swap() कॉल के साथ है: तो मैं कुछ इस तरह से करते हैं। मुझे एक त्रुटि मिलती है: "Non-const lvalue reference to type 'shared_ptr<EidosValue>' cannot bind to a value of unrelated type 'shared_ptr<EidosValue_Int_vector>'"। यह परेशान है क्योंकि EidosValue_Int_vector "असंबंधित प्रकार" नहीं है, यह ईडोसवेल्यू का एक सार्वजनिक उप-वर्ग है, और यहां कोड यह जानता है। अगर मैं result = make_shared<EidosValue_Int_vector>(); टाइप करता हूं तो संकलक को इसके साथ कोई समस्या नहीं है, इसलिए यह स्पष्ट रूप से जानता है कि प्रकार संबंधित और संगत हैं। यह किसी कारण से swap() के संदर्भ में इसे पसंद नहीं करता है। मेरे प्रोजेक्ट में अन्य स्थानों में मैं return int_result_SP; को घोषित रिटर्न प्रकार के साथ EidosValue_SP के साथ करने में सक्षम हूं, और यह ठीक काम करता है - संकलक उस संदर्भ में एक ईडोसवेल्यू_एसपी_एसपी होने के लिए ईडोसवेल्यू_आईएनटी_वेक्टर_एसपी पर विचार करने में प्रसन्न है - लेकिन मैं ' फ़ंक्शन के निचले भाग में साझा तर्क के कारण ऐसा नहीं करते हैं।

मैं यहां कुछ हद तक अपने कार्यान्वयन में बाध्य हूं क्योंकि यह कोड एक बाधा है और इसे तेजी से चलाने की जरूरत है (और हाँ, मुझे पता है कि वास्तव में कोड को मापने से, और हाँ, यह वास्तव में मायने रखता है)। तो डबल आवंटन से बचने के लिए make_shared का उपयोग करना आवश्यक है, और जब मैं सूचक को int_result_SP से पॉइंटर को परिणाम देता हूं तो मैं रेफकाउंट वृद्धि/कमी से बचने के लिए दृढ़ता से प्राथमिकता देना चाहूंगा; मैं नहीं चाहता कि समय में एक पल बनें जब दो share_ptrs नए उदाहरण को इंगित करते हैं। तो swap() जाने का स्पष्ट तरीका लगता है; लेकिन मैं इस कंपाइलर त्रुटि से अवरुद्ध हूँ। यह क्यों हो रहा है और मैं इसे कैसे ठीक कर सकता हूं? धन्यवाद!

परिशिष्ट:

ओह, इस आगे मुझे यकीन है मैं जानता हूँ कि क्यों त्रुटि हो रहा है विचार। swap() को EidosValue_Int_vector को EidosValue_SP में डालने पर कोई आपत्ति नहीं है, लेकिन को EidosValue_Int_vector_SP में डालने में समस्या है; उस दिशा में प्रकार संगत नहीं हैं। मैंने इस बारे में सोचा नहीं था क्योंकि result के पास कोई मूल्य नहीं है (यानी nullptr है, मुझे लगता है) इसमें; लेकिन निश्चित रूप से swap() यह नहीं जानता है। ठीक है, तो अगर यह समस्या है, तो सवाल यह है कि कोड को तेज़ी से रखते हुए स्थानांतरण को कैसे प्रभावित किया जा सकता है - एक रेफकाउंट इंक/डीसी नहीं कर रहा है और make_shared का उपयोग करने से दूर नहीं जा रहा है?अब जब कि मैं इस समस्या (मुझे लगता है कि) यह संभावना लगती है बस कुछ एपीआई या चाल है कि मैं अनदेखा कर दिया है कि वहाँ ...

उत्तर

4

यह ठीक है std::move के लिए है। उपयोग करें:

result = std::move (int_result_SP); 
5

समझ में आप कर सकते हैं नहीं swap, क्योंकि यद्यपि EidosValue_Int_vectorएकEidosValue बातचीत प्रतिसाद नहीं है ' सच नहीं है

+0

हाँ, मुझे लगा कि पोस्ट पर क्लिक करने के ठीक बाद। मैंने जो जोड़ा है उसे देखें। प्रश्न यह है कि मेरा कोड कैसे काम करें। – bhaller

+2

बस 'परिणाम = int_result_SP; '। कोई स्वैप की आवश्यकता नहीं है – qehgt

+0

"कोड को तेज़ी से रखते हुए" - आपको क्या लगता है कि असाइनमेंट आपके कोड को ** ** तेज नहीं कर रहा है? – YePhIcK

संबंधित मुद्दे