2017-05-08 7 views
5

मेरे दृष्टिकोण है:कच्चे सूचक से std :: unique_ptr से स्वामित्व को सही तरीके से कैसे स्थानांतरित करें?

class SomeClass 
{ 
    std::vector<std::unique_ptr<MyObject>> myObjects; 
public: 
    void takeOwnership(MyObject *nowItsReallyMyObject) 
    { 
     myObjects.emplace_back(std::move(nowItsReallyMyObject)); 
    } 
}; 

Am मैं सही ढंग से सब कुछ कर या वहाँ किसी भी बेहतर समाधान कर रहे हैं?

+0

आपको 'std :: move' की आवश्यकता नहीं है। – juanchopanza

+0

एक आदिम प्रकार (एक सूचक) –

उत्तर

4

move अनावश्यक है।

मैं स्वयं, मैं यह कर चाहते हैं:

void takeOwnership(std::unique_ptr<MyObject> nowItsReallyMyObject) 
{ 
    myObjects.emplace_back(std::move(nowItsReallyMyObject)); 
} 

क्योंकि मैं unique_ptr स्वामित्व अर्थ विज्ञान जहाँ तक "बाहर" संभव के रूप में स्थानांतरित करने के लिए चाहते हैं।

मैं इस उपयोगिता समारोह में लिख सकते हैं:

template<class T> 
std::unique_ptr<T> wrap_in_unique(T* t) { 
    return std::unique_ptr<T>(t); 
} 

तो कॉल कर सकते हैं:

foo.takeOwnership(wrap_in_unique(some_ptr)); 

लेकिन और भी बेहतर है, तो सीमाओं unique_ptr अर्थ विज्ञान बाहर की जहाँ तक वे यथोचित कर सकते हैं धक्का कर सकते हैं।

मैं भी कर सकता:

template<class T> 
std::unique_ptr<T> wrap_in_unique(T*&& t) { 
    auto* tmp = t; 
    t = 0; 
    return std::unique_ptr<T>(tmp); 
} 
template<class T> 
std::unique_ptr<T> wrap_in_unique(std::unique_ptr<T> t) { 
    return std::move(t); 
} 

कॉल संक्रमण आसान उनके T*unique_ptr में देता है। उनके सभी T* ->unique_ptr<T> अब std::move में लपेटा गया है, और स्रोत पॉइंटर शून्य है।

तो अगर वे

struct I_am_legacy { 
    T* I_own_this = 0; 
    void GiveMyStuffTo(SomeClass& sc) { 
    sc.takeOwnership(wrap_in_unique(std::move(I_own_this))); 
    } 
}; 

कोड था के रूप में तब्दील किया जा सकता है:

struct I_am_legacy { 
    std::unique_ptr<T> I_own_this; 
    void GiveMyStuffTo(SomeClass& sc) { 
    sc.takeOwnership(wrap_in_unique(std::move(I_own_this))); 
    } 
}; 

और यह अभी भी संकलित करता है तथा एक ही काम करता है। (I_own_this के साथ अन्य बातचीत को बदलना पड़ सकता है, लेकिन इसका हिस्सा पहले से ही अद्वितीय_ptr संगत होगा)।

2

आप से unique_ptr को स्वीकार करना चाहिए मिल-जाना:

class SomeClass 
{ 
    std::vector<std::unique_ptr<MyObject>> myObjects; 
public: 
    // tells the world you 0wNz this object 
    void takeOwnership(std::unique_ptr<MyObject> myObject) 
    { 
     myObjects.push_back(std::move(myObject)); 
    } 
}; 

इस तरह से आप यह स्पष्ट आप स्वामित्व लेने और आप भी कच्चे संकेत का उपयोग कर से बचने के लिए अन्य प्रोग्रामर मदद कर सकते हैं।

अतिरिक्त पठन: CppCoreGuidelines R.32

+0

धन्यवाद पर 'std :: move' को कॉल करने का कोई मतलब नहीं है। लेकिन मुझे [CppCoreGuidelines R.33] में रुचि है (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#r33-take-a-unique_ptrwidget-parameter-to-express-that-a समारोह-reseats-thewidget)। मुझे रेफरी द्वारा myObject लेने की आवश्यकता है क्योंकि मैं नहीं चाहता कि इसे फ़ंक्शन रिटर्न के बाद हटा दिया जाए। इसके अलावा वीएस2013 का कहना है कि यदि मैं इसे वैल द्वारा पास करने का प्रयास करता हूं तो फ़ंक्शन हटा दिया जाता है। या मैं गलत हूँ? – Oliort

+0

@Oliort फ़ंक्शन रिटर्न के बाद इसे हटाया नहीं जाएगा क्योंकि आप अपने वेक्टर के अंदर 'std :: unique_ptr' में 'std :: move()' हैं। 'Std :: move' के बाद पैरामीटर संस्करण 'nullptr' बन जाता है – Galik

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