2010-10-08 7 views
7

मैं पूरे दिन नामित नामस्थानों के बारे में लेख पढ़ रहा हूं, अधिकांश लेखों को समझाया गया है जब आपको स्थैतिक कीवर्ड पर अनाम नामों का उपयोग करना चाहिए। लेकिन मैं अभी भी एक बड़े सवाल के साथ छोड़ दिया गया है जब स्थिर का उपयोग करना उचित है? आखिरकार इसे पूरी तरह से बहिष्कृत नहीं किया गया है, स्थिर कार्यों वाले हेडर फ़ाइलों के बारे में क्या मुझे उन्हें नामांकित नामस्थान में रखना चाहिए?सी ++ में स्थैतिक (अज्ञात नामस्थानों पर) का उपयोग करना उचित कब है?

#ifndef HEADER_H 
#define HEADER_H 

static int func() { 
    ... 
} 

// versus: 

namespace { 
    int func() { 
    ... 
    } 
}; 

#endif // HEADER_H 

या स्थैतिक सदस्य कार्यों के बारे में क्या?

अभिवादन

+7

हेडर फ़ाइलों में स्थैतिक (या अनाम नामसेस्पेस) रखने के लिए काउंटर उत्पादक लगता है। यदि वे स्थिर हैं तो वे सिर्फ स्रोत फ़ाइल में क्यों नहीं हैं? –

उत्तर

3

वहाँ अनाम नामस्थान जो मैं के बारे में पता से अधिक नाम स्थान दायरे में स्थिर का कोई फायदा नहीं है। ऊपर दिए गए उदाहरण में, अनाम नामों का उपयोग करें। असल में ऊपर दिए गए उदाहरण में मैं नहीं देख सकता कि स्थैतिक या अनाम नामस्थान क्यों आवश्यक है। शायद इनलाइन? और स्थैतिक सदस्य कार्यों के पास नेमस्पेस दायरे पर स्थिर के साथ कुछ भी नहीं है। स्टेटिक सदस्य फ़ंक्शन (और गैर-कार्य सदस्य) अभी भी मान्य हैं।

+0

उदाहरण में बाहरी लिंकिंग वाले फ़ंक्शन से बचने के लिए स्थिर की आवश्यकता है। चूंकि इसे हेडर का उपयोग करने वाले प्रत्येक मॉड्यूल में लागू किया जाएगा, इसलिए स्थिर कीवर्ड मौजूद नहीं होने पर लिंकर ऑब्जेक्ट कर सकता है। –

+0

@Alexander: ठीक है, इनलाइन फ़ंक्शन की कई परिभाषाओं की अनुमति देगा। और मेरी राय में एक बेहतर विकल्प है। हालांकि, यदि "आंतरिक लिंक" बिल्कुल जरूरी है, तो नामित नेमस्पेस बहुत बेहतर है, कम से कम क्योंकि इसे बहिष्कृत नहीं किया गया है। –

+4

'इनलाइन' फ़ंक्शन की एकाधिक * समान * परिभाषाओं की अनुमति देता है। 'स्थिर 'कई अलग-अलग परिभाषाओं की अनुमति देता है, क्योंकि प्रत्येक अनुवाद इकाई के पास आंतरिक संबंध के साथ अपना स्वयं का कार्य होता है, इसलिए उन्हें उसी नाम से संदर्भित किया जाता है। इसलिए, यदि 'func' की परिभाषा में कुछ है जो कुछ # परिभाषाओं (जैसे' assert') पर निर्भर करता है, और आप अलग-अलग टीयू को गठबंधन करना चाहते हैं जिसमें शीर्षलेख #define में विभिन्न मानों के साथ शामिल है, तो आपको या तो 'स्थिर' या एक अनाम नामस्थान की आवश्यकता होगी। 'इनलाइन' आधिकारिक तौर पर नहीं करेगा, हालांकि व्यवहार में यह काम कर सकता है। –

5

मानक के सटीक शब्दों है: जब नाम स्थान दायरे में वस्तुओं की घोषणा

static कीवर्ड के उपयोग नहीं किया जाता।

एक हेडर फाइल में

कार्य inline बजाय static या एक अनाम नाम स्थान में होना चाहिए। inline का अर्थ है कि आप केवल अपने प्रोग्राम में फ़ंक्शन की अधिकांश प्रतियों के साथ समाप्त हो जाएंगे, जबकि अन्य विधियां आपको प्रत्येक फ़ाइल से एक अलग प्रतिलिपि देंगी जिसमें हेडर शामिल है। साथ ही ब्लोट, यदि फ़ंक्शन में फ़ंक्शन-स्टेटिक डेटा होता है तो यह गलत व्यवहार दे सकता है। (संपादित करें: जब तक कि फ़ंक्शन को अलग-अलग संकलन इकाइयों में अलग-अलग परिभाषाएं नहीं माना जाता है, शायद हेडर फ़ाइल को शामिल करने से पहले परिभाषित किए गए विभिन्न प्रीप्रोसेसर मैक्रोज़ के कारण। उस स्थिति में सबसे अच्छा तरीका यह बिल्कुल शामिल नहीं करना है, बल्कि इसे अपने अपवित्र दिल के माध्यम से एक हिस्सेदारी के साथ एक अनजान कब्र में दफनाने के लिए।)

स्थिरांक के अलावा डेटा ऑब्जेक्ट्स को आमतौर पर हेडर फाइलों में परिभाषित नहीं किया जाना चाहिए, केवल extern घोषित किया जाना चाहिए।

स्टेटिक सदस्य फ़ंक्शन मछली की एक अलग केतली हैं, और आपको static का उपयोग करना होगा क्योंकि उन्हें घोषित करने का कोई अन्य तरीका नहीं है। उस उपयोग को बहिष्कृत नहीं किया गया है, क्योंकि यह नामस्थान क्षेत्र में नहीं है।

अद्यतन: सी ++ 11 ने बहिष्करण को हटा दिया है, इसलिए static पर अनाम नामों को पसंद करने का कोई विशेष कारण नहीं है। लेकिन आपको अभी भी हेडर फ़ाइल में तब तक उपयोग नहीं करना चाहिए जब तक आप कुछ अजीब नहीं कर रहे हों।

+0

"डेटा ऑब्जेक्ट्स को हेडर फाइलों में बिल्कुल परिभाषित नहीं किया जाना चाहिए, अगर उन्हें बाह्य संबंध की आवश्यकता हो तो केवल बाहरी घोषित किया जाना चाहिए।" यह अपरिहार्य है। "डेटा ऑब्जेक्ट", जैसा कि आप उन्हें कॉल करते हैं, डिफ़ॉल्ट रूप से बाहरी लिंकेज होते हैं, जब तक कि वे स्थिर न हों। इसलिए उनकी घोषणा केवल एक घोषणा करने के लिए बाहरी है और परिभाषा नहीं, जो डिफ़ॉल्ट है। हालांकि अगर दोनों बाहरी और प्रारंभिक मौजूद हैं, तो यह एक परिभाषा है। –

+0

डेटा ऑब्जेक्ट्स को अक्सर हेडर फ़ाइलों में परिभाषित करने की आवश्यकता होती है। इसमें स्थिरांक (जो वस्तुएं हैं) शामिल हैं। मुझे लगता है कि हेडर फाइलों में गैर-अभिन्न प्रकारों के परिभाषित (स्थैतिक वर्ग सदस्य) स्थिरांक से बचने के लिए सी ++ नौसिखियों के लिए यह अच्छी सलाह है। अधिक अनुभवी प्रोग्रामर ऐसा कर सकते हैं उदा। टेम्पलेटेड स्थिरांक चाल। एक और ऐसी चाल एक स्थानीय स्थैतिक स्थिरता के संदर्भ में एक समारोह है। –

+0

@ आर्मेन, @ एएलएफ: हाँ, डेटा ऑब्जेक्ट्स से संबंधित मेरी सलाह थोड़ा सा सरल थी। मैं इसे फिर से भर दूंगा। –

3

हेडर फ़ाइल में आंतरिक लिंकेज निर्दिष्ट करने या अज्ञात नेमस्पेस का उपयोग करने में आमतौर पर कोई बिंदु नहीं है।

अलग-अलग संकलित कार्यान्वयन फ़ाइल में आप static या एक अज्ञात नेमस्पेस का उपयोग कर सकते हैं ताकि लिंक स्तर नाम टकराव या क्लाइंट कोड कार्यान्वयन विवरण पर निर्भर हो सकें। एक अज्ञात नेमस्पेस आपको बाहरी लिंकेज देता है, जो टेम्पलेट पैरामीटर के लिए आवश्यक है, और यह कक्षा परिभाषाओं का भी समर्थन करता है। लेकिन अंत में यह मामले के आधार पर व्यावहारिकता और व्यक्तिगत वरीयता का सवाल है।

static किसी सदस्य फ़ंक्शन के लिए लिंकेज विनिर्देशन से कोई लेना देना नहीं है। static सदस्य फ़ंक्शन में बाहरी लिंकेज है।

0

static कुछ उपकरण का उपयोग कर रहे हैं तो बेहतर हो सकता है। यह अधिकांश टेक्स्ट संपादकों में ऑटो इंडेंट कार्यक्षमता के साथ थोड़ा बेहतर व्यवहार करता है। यह थोड़ा दुखी है, जब आपको कुछ उपयोगी उपयोग करने से बचना होता है क्योंकि यह उन उपकरणों के साथ काम नहीं करता है जो वास्तव में इसका समर्थन करना चाहिए, लेकिन मैं वादा करता हूं कि आप इसे प्राप्त करेंगे।

एक उदाहरण सवाल है कि डिबगिंग विभाग में संभावित दर्द के कुछ संकेत देता है:

Viewing namespaced global variables in Visual Studio debugger?

आप शायद अधिक समस्याओं को खोजने के लिए बहुत कठिन देखने के लिए नहीं होगा, लेकिन डिबगर मुद्दों के लिए पर्याप्त थे मुझे अधिकतम सीमा तक, नामस्थानों पर पूरी तरह से छोड़ दें, इसलिए मैंने कभी और आगे नहीं देखा है।

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

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