दिलचस्प पोस्ट
जावा में: कैसे बाइट सरणी से फ़ाइल ज़िप? दूसरी कॉल पर एचटीटीपी वेबबर्म बार का समय प्रारंभिक क्षमता के साथ एक अर्रेलिस्ट शुरू क्यों करें? फोन-गैप-जावास्क्रिप्ट क्रॉस-डोमेन अजाक्स अनुरोध भेज रहा है कई सीपीपीएस में एक ही हेडर को शामिल करने से कई परिभाषा त्रुटियां दोहराई गईं कैसे जावा में वर्णों को जोड़ना है? आप बैश में एक फ़ाइल पथ को सामान्य कैसे करते हैं? IList <टी> पर द्विआधारी खोज कैसे करें? वैश्विक ध्वज के साथ एक RegExp गलत परिणाम क्यों दे रहा है? आपके .vimrc में क्या है? उत्पत्ति http: // localhost: 3000 प्रवेश-नियंत्रण-अनुमति-मूल द्वारा अनुमति नहीं है मैं autoload के साथ PHP नामस्थान का उपयोग कैसे करूं? मैं उप-निर्देशिका में एक सबमोड कैसे जोड़ूं? मैं UITextField में दशमलव बिंदुओं की संख्या को कैसे सीमित कर सकता हूँ? IDisposable के साथ Excel इंटरऑप ऑब्जेक्ट साफ़ करें

सिंगलटन इंस्टेंस को गेटइंस्टेंस विधि के स्थिर वैरिएबल के रूप में घोषित किया गया

मैंने सिंगलटन पैटर्न के कार्यान्वयन को देखा है जहां उदाहरण चर को GetInstance विधि में स्थिर वैरिएबल के रूप में घोषित किया गया था। इस कदर:

SomeBaseClass &SomeClass::GetInstance() { static SomeClass instance; return instance; } 

मैं इस दृष्टिकोण के निम्नलिखित सकारात्मक पक्षों को देखता हूं:

  • यह कोड सरल है, क्योंकि यह संकलक है जो इस ऑब्जेक्ट को केवल तभी निर्मित करने के लिए जिम्मेदार था जब GetInstance को पहली बार कहा जाता था।
  • कोड सुरक्षित है, क्योंकि उदाहरण के संदर्भ में कोई अन्य तरीका नहीं है, लेकिन गेटइंस्टेंस पद्धति के साथ और उदाहरण को बदलने का कोई दूसरा तरीका नहीं है, लेकिन गेट इंस्टेंस पद्धति के अंदर।

इस दृष्टिकोण के नकारात्मक पक्ष क्या हैं (सिवाय इसके कि यह बहुत ही OOP-ish नहीं है)? यह धागा सुरक्षित है?

Solutions Collecting From Web of "सिंगलटन इंस्टेंस को गेटइंस्टेंस विधि के स्थिर वैरिएबल के रूप में घोषित किया गया"

सी ++ 11 में यह धागा सुरक्षित है:

§6.7 [stmt.dcl] p4 यदि परिवर्तक प्रारंभिक रूप से घोषित होने पर घोषणा में प्रवेश करती है, तो समवर्ती निष्पादन प्रारंभिककरण के पूरा होने की प्रतीक्षा करेगा।

सी ++ 03 में:

  • जी ++ के तहत यह धागा सुरक्षित है।
    लेकिन इसका कारण यह है कि जी ++ स्पष्ट रूप से कोड की गारंटी देता है।

एक समस्या यह है कि यदि आपके पास दो एकल गीत हैं और वे एक दूसरे के निर्माण और विनाश के दौरान प्रयास करते हैं और उपयोग करते हैं

इसे पढ़ें: ढूँढना सी ++ स्थैतिक आरंभीकरण आदेश समस्याओं

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

इसके चारों ओर तरीके हैं लेकिन वे गड़बड़ हैं और ऐसा करने के लायक नहीं हैं बस एक वैश्विक चर के डिस्ट्रक्टर से सिंगलटन तक पहुंच नहीं सकते हैं।

एक सुरक्षित परिभाषा, लेकिन बदसूरत:
मुझे यकीन है कि आप कुछ उचित मैक्रोज़ को साफ करने के लिए जोड़ सकते हैं

 SomeBaseClass &SomeClass::GetInstance() { #ifdef _WIN32 Start Critical Section Here #elif defined(__GNUC__) && (__GNUC__ > 3) // You are OK #else #error Add Critical Section for your platform #endif static SomeClass instance; #ifdef _WIN32 END Critical Section Here #endif return instance; } 

यह धागा सुरक्षित नहीं दिखाया गया है। सी ++ भाषा धागे पर चुप है, इसलिए आपके पास भाषा से अंतर्निहित गारंटी नहीं है। आपको प्लेटफ़ॉर्म सिंक्रनाइज़ेशन primitives का उपयोग करना होगा, जैसे Win32 :: EnterCriticalSection (), पहुंच को सुरक्षित करने के लिए।

आपका विशेष दृष्टिकोण समस्याग्रस्त बी / सी होगा, कम्पाइलर पहले अभिविन्यास पर स्थिर instance को प्रारंभ करने के instance कुछ (गैर-थ्रेड सुरक्षित) कोड को सम्मिलित करेगा, संभवतः फ़ंक्शन बॉडी को निष्पादन शुरू होने से पहले (और इसलिए किसी भी सिंक्रनाइज़ेशन को लागू किया जा सकता है ।)

कुछ SomeClass वैश्विक / स्थैतिक सदस्य सूचक का उपयोग करना और फिर सिंक्रनाइज़ किए गए ब्लॉक के भीतर आरंभ करने से इसे कार्यान्वित करने के लिए कम समस्याग्रस्त साबित होगा।

 #include <boost/shared_ptr.hpp> namespace { //Could be implemented as private member of SomeClass instead.. boost::shared_ptr<SomeClass> g_instance; } SomeBaseClass &SomeClass::GetInstance() { //Synchronize me eg ::EnterCriticalSection() if(g_instance == NULL) g_instance = boost::shared_ptr<SomeClass>(new SomeClass()); //Unsynchronize me eg :::LeaveCriticalSection(); return *g_instance; } 

मैंने इसे संकलित नहीं किया है इसलिए यह केवल उदाहरण के लिए ही है यह आपके मूल उदाहरण के समान जीवनकाल (या इसके बारे में) प्राप्त करने के लिए बढ़ावा पुस्तकालय पर निर्भर करता है आप std :: tr1 (C ++ 0x) का भी उपयोग कर सकते हैं

चश्मे के अनुसार, यह भी वीसी ++ में काम करना चाहिए किसी को भी पता है अगर यह करता है?

बस खोजशब्द अस्थिरता जोड़ें यदि msdn पर डॉक्टर सही है तो विज़ुअल सी ++ कंपाइलर को म्यूटक्स उत्पन्न करना चाहिए।

 SomeBaseClass &SomeClass::GetInstance() { static volatile SomeClass instance; return instance; } 

यह सिंगलटन कार्यान्वयन के सभी सामान्य असफलताओं को साझा करता है, अर्थात्:

  • यह अघोषित है
  • यह धागा सुरक्षित नहीं है (यह देखने के लिए काफी कम है कि क्या आप एक ही समय में फ़ंक्शन में प्रवेश करने वाले दो धागे की कल्पना करते हैं)
  • यह स्मृति रिसाव है

मैं कभी भी किसी भी उत्पादन कोड में सिंगलटन का उपयोग नहीं करने की सलाह देता हूं।