2016-10-25 8 views
5

निम्न कोड के लिए:विनाश आदेश

class C { 
public:  
    static C& Instance() { 
     static C c; 
     return c; 
    } 

    ~C(){std::cout << "c destructed\n";} 
private: 
    C(){} 
}; 

class D{//similar to C but prints `d destructed` on destruction 
//... 

int main() 
{ 
    auto c = C::Instance(); 
    auto d = D::Instance(); 
} 
//outputs (with gcc) 
//d destructed 
//c destructed 
//d destructed 
//c destructed 

मैं सवालों की एक जोड़ी:

  1. विनाश के आदेश अच्छी तरह से परिभाषित कॉल है? (भले ही कक्षा सी और डी को अलग-अलग स्रोत-फाइलों में परिभाषित किया गया हो)
  2. यदि यह अच्छी तरह से परिभाषित किया गया है तो यह व्यवहार पोर्टेबल है?
+0

मुझे नहीं लगता कि मानक वास्तव में यह परिभाषित करता है, के रूप में यह वैश्विक के विनाश के क्रम को परिभाषित नहीं करता ऑब्जेक्ट्स, केवल वे रिवर्स ऑर्डर में नष्ट हो जाते थे, जहां उन्होंने –

+0

का निर्माण किया था विनाश का आदेश एक [अनुवाद इकाई] (https://en.wikipedia.org/wiki/Translation_unit_ (प्रोग्रामिंग) के भीतर अच्छी तरह से परिभाषित किया गया है)। लेकिन अनुवाद इकाइयों के बीच नहीं। –

+0

[एक संबंधित प्रश्न और उत्तर] (http://stackoverflow.com/q/246564/440558)। –

उत्तर

7

इस संरचना की बात एक निर्माण लागू करने के क्रम है (और इस प्रकार एक विनाश आदेश)।

निर्माण

चूंकि इन स्थानीय स्थैतिक चर रहे हैं, निर्माण के आदेश जिस क्रम में अपने-अपने Instance कार्यों पहली बार के लिए कहा जाता है से निर्धारित होता है।

चूंकि यह main में किया गया है, निर्माण आदेश पूरी तरह से निर्दिष्ट है।

आदेश अनिर्दिष्ट बनाने के लिए एक ही रास्ता है अगर आप उदाहरण के लिए अलग अलग अनुवाद इकाइयों में स्थिर initialisation में उन्हें इस्तेमाल, अगर एक

C& the_c = C::Instance(); 

है और अन्य है

D& the_d = D::Instance(); 

विनाश

स्थिर भंडारण वाले वस्तुओं का विनाश निर्माण के आदेश के विपरीत है।

3.6.3, समाप्ति, अनुच्छेद 1:

निर्माता या स्थिर भंडारण अवधि के साथ एक वस्तु के गतिशील आरंभीकरण के पूरा होने एक और, के नाशक के पूरा होने की है कि इससे पहले कि अनुक्रम है, तो दूसरा को पहले के विनाशक की शुरुआत से पहले अनुक्रमित किया गया है।

तो विनाश आदेश पूरी तरह से निर्माण आदेश द्वारा निर्दिष्ट किया गया है।

ध्यान दें कि यह सिंगलटन निर्माण अच्छी तरह से निर्दिष्ट है भले ही उनमें से एक अनुवाद इकाई के बावजूद दूसरे पर निर्भर करता है।

है यही कारण है, यह पूरी तरह से सुरक्षित है, और यह कोई फर्क नहीं पड़ता है जहाँ यह परिभाषित किया है:

class C { 
public:  
    static C& Instance() { 
     static C c(D::Instance()); 
     return c; 
    } 

    ~C(){ m_d.doSomething(); } // Yes, this is safe. 
private: 
    C(D& d) : m_d(d) { m_d.doSomething(); } // Yes, this is safe. 
    D& m_d; 
}; 
-1

सामान्य रूप से, स्थैतिक स्थानीय चर (जो आपके मामले में उपयोग किए जाते हैं) सहित स्थैतिक वस्तुओं के विनाश का आदेश अनिर्धारित है।

विनाश के आदेश को सुनिश्चित करने के लिए, एक पैटर्न जिसका मैंने उपयोग किया है वह std :: shared_ptr पर लाभ उठाने के लिए है। उदाहरण के लिए, यदि आप सी सिंगलटन सुनिश्चित करना चाहते हैं मान्य रहती है जब तक के बाद डी सिंगलटन नष्ट हो जाता है, तो आप एक shared_ptr < C> डी में संग्रहीत कर सकती है:

class C { 
    static shared_ptr<C> Instance() { 
    static auto c = make_shared<C>(); 
    return c; 
    } 
}; 

class D { 
    static shared_ptr<D> Instance() { 
    static auto d = make_shared<D>(); 
    return d; 
    } 

    D(): c_(C::Instance()) {} 

private: 
    shared_ptr<C> c_; 
}; 
+0

[molbdnilo का जवाब] (http://stackoverflow.com/a/40243538/4115625) विनाश के आदेश की व्याख्या की, -1 – Danh

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