2009-09-07 4 views
8

चीयर्स,सी ++ में स्थिर उदाहरण के माध्यम से सिंगलेट्स - स्रोत में या हेडर फाइलों में?

मैं "उदाहरण से प्रोग्रामिंग खेल ऐ" में कोड के इस खंड में भाग:

/* ------------------ MyClass.h -------------------- */ 
#ifndef MY_SINGLETON 
#define MY_SINGLETON 

class MyClass 
{ 
private: 

    // member data 
    int m_iNum; 

    //constructor is private 
    MyClass(){} 

    //copy ctor and assignment should be private 
    MyClass(const MyClass &); 
    MyClass& operator=(const MyClass &); 

public: 

    //strictly speaking, the destructor of a singleton should be private but some 
    //compilers have problems with this so I've left them as public in all the 
    //examples in this book 
    ~MyClass(); 

    //methods 
    int GetVal()const{return m_iNum;} 
    static MyClass* Instance(); 
}; 

#endif 

/* -------------------- MyClass.cpp ------------------- */ 

//this must reside in the cpp file; otherwise, an instance will be created 
//for every file in which the header is included 
MyClass* MyClass::Instance() 
{ 
    static MyClass instance; 

    return &instance; 
} 

मैं लेखक कि स्थिर घोषित चर द्वारा बात-की-तथ्य बयान से उलझन में हूँ शीर्षलेख में किसी फ़ंक्शन के अंदर एकाधिक, अलग स्थैतिक चर instance घोषित करने का परिणाम होगा। मुझे नहीं लगता कि मैंने इस व्यवहार को getInstance() फ़ंक्शन के सामान्य कार्यान्वयन में देखा है जिसे मैं नियमित रूप से हेडर में डालता हूं (सिवाय इसके कि मुझे पॉइंटर्स के साथ खेलना और सिंगलटन को पहले उपयोग पर प्रारंभ करना पसंद है)। मैं अपने काम के लिए जीसीसी का उपयोग कर रहा हूं।

तो मानक क्या कहता है? गैर-अनुपालन कंपाइलर्स क्या कहते हैं? क्या लेखक का कथन सही है, और यदि हां, तो क्या आप कुछ कंपाइलर्स नाम दे सकते हैं जो getInstance() शीर्षलेखों में घोषित किए गए थे तो कई उदाहरण बनाएंगे?

+4

सी ++ में थ्रेड-सुरक्षा के साथ सिंगलटन को कार्यान्वित करने के बारे में एक अच्छी चर्चा इस पेपर में पाई जा सकती है: http://www.aristeia.com/Papers/DDJ%5FJul%5FAug%5F2004%5Frevised .pdf –

उत्तर

10

C++ में कुछ भी नहीं है एक इनलाइन समारोह को रोकने के लिए एक स्थिर चर है और संकलक (जैसे कि यह टेम्पलेट इन्स्टेन्शियशन स्थिर वर्ग के सदस्यों और स्थिर समारोह चर के लिए यह करने के लिए है) सब अनुवाद इकाइयों के बीच उस चर आम बनाने के लिए व्यवस्था करने के लिए है। 7.1.2/4

staticextern inline फ़ंक्शन में परिवर्तनीय हमेशा एक ही ऑब्जेक्ट को संदर्भित करता है।

ध्यान दें कि सी में, इनलाइन फ़ंक्शंस में स्थैतिक चर नहीं हो सकते हैं (न ही आंतरिक संबंध के साथ ऑब्जेक्ट का संदर्भ)।

+0

दूसरे शब्दों में, myclass.h में 'स्थिर इनलाइन फ़ंक्शन' में परिभाषित एक 'स्थैतिक चर' परिणामस्वरूप लिंक किए गए कोड में केवल एक बार दिखाई देगा, और स्रोत फ़ाइलों (जैसे main.cpp, myclass.cpp के बीच साझा किया जाएगा) और joetheplumber.cpp)? मूविंग :: उपरोक्त कोड से इंस्टेंस() में हेडर में अभी भी एक ही इंस्टेंस को अलग-अलग .cpp फ़ाइलों पर वापस लौटने की गारंटी होगी? –

+0

जब तक संकलक अनुरूप है।चूंकि मुझे कोई समस्या याद नहीं है और टेम्पलेट के लिए क्षमता की आवश्यकता है, मुझे उस बिंदु पर कोई डर नहीं है। – AProgrammer

+1

इस के साथ हालिया समस्याओं के बारे में नहीं सुना है, न ही वीसी 6 या जीसीसी 2.95 में। – MSalters

1

मैंने कोड को कोशिश की है कि ओपी ने वीएस -2008 के साथ चार तरीकों से पोस्ट किया है और MyClass के स्थिर उदाहरण के साथ MyClass::Instance() में कोई समस्या नहीं प्रतीत होती है।

  1. Instance() MyClass.cpp में परिभाषित किया गया है: यह सामान्य तरीके सब कुछ ठीक है।
  2. Instance() केवल कक्षा घोषणा के भीतर परिभाषित किया गया है। यह विकल्प है और सबकुछ ठीक है।
  3. Instance()inline कक्षा के बाहर परिभाषित किया गया है, लेकिन शीर्षक में और सब कुछ ठीक है।
  4. 3. के रूप में लेकिन inline और लिंकर बिना कहते हैं की Instance()

मुझे लगता है कि किताब लेखक ऊपर 4. के साथ संबंध है एकाधिक परिभाषाएँ देखते हैं और जानते हैं कि MyClass के स्थिर उदाहरण हो जाएगा संकलन और लिंक जो एक कार्यक्रम में ख्याल रखा।

+0

मैं आपको स्वीकार्य मानता हूं, लेकिन मैंने पहले से ही एप्रामोग्रामर के साथ ऐसा किया है और मैं टिक को स्विच करने के बारे में वास्तव में बुरा महसूस करता हूं। तो यहां एक बहुत ही स्पष्ट तर्क के लिए सिर्फ एक उथल-पुथल है। –

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