2017-02-09 17 views
11

को शामिल निम्नलिखित कोड पर विचार करें:बारे में सुरक्षित संचालन अद्वितीय संकेत

#include <memory> 

struct Foo { std::unique_ptr<Foo> next; }; 
void f(Foo &foo) { foo = std::move(*foo.next); } 

int main() { 
    Foo foo{}; 
    foo.next = std::make_unique<Foo>(); 
    foo.next->next = std::make_unique<Foo>(); 
    f(foo); 
} 

foo = std::move(*foo.next); करने से, foo.next.nextfoo.next में ले जाया गया है।
यदि foo.next को पहले चरण के रूप में अमान्य किया गया है, तो ऑब्जेक्ट जिस पर इसे इंगित किया जा सकता है तुरंत हटा दिया जा सकता है। इससे foo.next.next को हटाना होगा, यह वह ऑब्जेक्ट है जिसे मैं foo.next पर ले जाने की कोशिश कर रहा हूं।
मुझे यकीन है कि मुझे अपने तर्क में कुछ याद आ रहा है, लेकिन मुझे पता नहीं चल रहा कि क्या गलत है।
क्या यह एक सुरक्षित संचालन है? मानक मुझे इसके बारे में कहां आश्वस्त करता है?

उत्तर

7

मुझे लगता है कि यह पूरी तरह से सुरक्षित है। जब आप पर f() फ़ंक्शन को कॉल करते हैं, तो class Foo के चाल असाइनमेंट ऑपरेटर std::unique_ptr<Foo>::operator=(std::unique_ptr<Foo>&&) का आह्वान करेंगे। अब, सी ++ 14 मानक, §20.8.1.2.3, अल्पविराम 2, का कहना है: के रूप में अगर reset(u.release())get_deleter() = std::forward<D>(u.get_deleter()) के बाद फोन करके *this करने के लिए u से स्थानांतरण स्वामित्व:

प्रभाव।

प्रभाव::

§20.8.1.2.5 में अल्पविराम 4, हम reset() के व्यवहार को खोजने संग्रहीत सूचक को p प्रदान करती है, और फिर अगर संग्रहीत के पुराने मूल्य सूचक, old_p, nullptr के बराबर नहीं था, get_deleter()(old_p) पर कॉल करता है। [नोट: इन परिचालनों का क्रम महत्वपूर्ण है क्योंकि get_deleter() पर कॉल *this को नष्ट कर सकता है। अंत टिप्पणी]

तो, हम बहस कर सकते हैं कि संग्रहीत सूचक प्रतिस्थापित किया जाएगा और तोवर्ष संग्रहीत सूचक इस क्रम में, हटा दिया जाएगा। इस प्रकार, सबकुछ ठीक और अच्छी तरह से परिभाषित है।

इसके अलावा, जब आप reset() समारोह में में प्रवेश करेंगे, *foo.next वस्तु पहले से ही release() घ किया गया है जाएगा, ताकि उठाई वस्तु इसके साथ नष्ट नहीं किया जाएगा।

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