2012-03-28 18 views
7
//a.h 

extern int x1; 
static int x2; 
int x3; 
static const int x4; 

class A { 
    public: 
     static const int x5 = 10; 
}; 

a.h में const` कई .cpp फ़ाइलों से शामिल किया जाएगा, मेरे सवाल यह है:`static`,` extern`, `हेडर फाइल

1. x1 सिर्फ एक घोषणा है, हैं ना? तो इसकी परिभाषा उन .cpp फ़ाइलों में से एक में की जानी चाहिए, है ना?

2. x2 एक परिभाषा है, है ना? मुझे लगता था कि static int भी extern int की तरह एक घोषणा है, लेकिन मैं गलत था। x2 केवल a.h में दिखाई देगा?

3. , कई बार परिभाषित किया जाएगा यदि a.h कई .cpp फ़ाइलों में शामिल किया जाता है तो संकलन त्रुटि में परिणाम होगा, है ना?

4. x4 एक परिभाषा है, है ना?

5. कक्षा ए में, x5 एक घोषणा है, हां। लेकिन x4 के बारे में क्या?

+0

आइटम 5 में प्रश्न से आपका क्या मतलब है? –

+0

@ डेविड हेफरन, मेरा मतलब है कि 'x5' एक घोषणा क्यों है लेकिन' x4'? – Alcott

उत्तर

10

1.x1 सिर्फ एक घोषणा, है न? तो इसकी परिभाषा उन .cpp फ़ाइलों में से एक में की जानी चाहिए, है ना?

सही

2.x2 एक परिभाषा, है न? मुझे लगता था कि स्थैतिक int बाहरी int की तरह ही एक घोषणा है, लेकिन मैं गलत था। x2 केवल एएच में दिखाई देगा?

एक अलग x2 प्रत्येक अनुवाद इकाई में उपलब्ध होगा जिसमें हेडर शामिल है।

3.x3 एकाधिक .cpp फ़ाइलों में एएच शामिल होने पर कई बार परिभाषित किया जाएगा, इसलिए x3 संकलन-त्रुटि में परिणाम देगा, है ना?

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

4।x4 एक परिभाषा है, है ना?

हाँ, यह एक परिभाषा है, लेकिन x2 साथ के रूप में प्रत्येक अनुवाद इकाई यह x4 (दोनों static की वजह से खुद है और क्योंकि यह const है जो आंतरिक संबंध

5.Here का तात्पर्य होगा कक्षा एक में, x5 एक घोषणा है, हाँ। लेकिन क्या x4 के बारे में?

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

यह आखिरी मामला विशेष है। यह एकमात्र घोषणा (आईआईआरसी) है जहां घोषणा का मूल्य हो सकता है, और इसका कारण यह है कि यह संकलक को का उपयोग सभी अनुवाद इकाइयों में स्थिरता का मान देता है जिसमें संकलन समय स्थिर के रूप में हेडर शामिल है। यदि मूल्य परिभाषा के साथ प्रदान किया जाना था, तो केवल एक ही अनुवाद इकाई के पास उस मूल्य तक पहुंच होगी। कि स्थिर सदस्य की परिभाषा होगा:

const int A::x5; // no initialization here 

और तुम एक प्रदान करना होगा अगर सदस्य है ओडीआर रूप से प्रयुक्त। अब तथ्य यह है कि ज्यादातर मामलों में स्थिर odr-used नहीं होगा क्योंकि संकलक A::x5 अभिव्यक्ति का उपयोग करते समय मान को प्रतिस्थापित करेगा। आप, परिभाषा की जरूरत है केवल जब सदस्य एक lvalue के रूप में प्रयोग किया जाता है, उदाहरण के लिए:

void f(const int &) {} 
int main() { 
    f(A::x5); 
} 

क्योंकि f को तर्क एक संदर्भ है, A::x5 का उपयोग एक lvalue (ध्यान दें, स्थिरांक सत्ता की आवश्यकता है और lvalue/rvalue-ness लगभग ऑर्थोगोनल हैं), और इसके लिए आपके प्रोग्राम में एक एकल अनुवाद इकाई में सदस्य की परिभाषा की आवश्यकता होती है।

+0

'आंतरिक संबंध' क्या है? – Alcott

+0

@ एल्कॉट: प्रतीक को अनुवाद इकाई के बाहर से एक्सेस नहीं किया जा सकता है जिसमें इसे परिभाषित किया गया है। इसका तात्पर्य यह है कि यदि एकाधिक अनुवाद इकाइयां एक ही नाम से आंतरिक लिंक के साथ एक प्रतीक को परिभाषित करती हैं, तो प्रत्येक अनुवाद इकाई को अपना स्वयं का अलग-अलग प्रतीक मिलेगा (यानी अलग-अलग प्रतीकों को भले ही उनके नाम समान हों)। –

4
  1. सही

  2. यह एक परिभाषा x2 0 हो जाएगा, और हर अनुवाद इकाई है कि हेडर शामिल है x2 की अपनी एक प्रतिलिपि होगा।

  3. हां, लेकिन इसके परिणामस्वरूप एक लिंकर-त्रुटि होगी, संकलक नहीं।

  4. 2. जैसा ही है, लेकिन आप इसे संशोधित नहीं कर सकते।

  5. कक्षा के अंदर, static का एक अलग अर्थ है। यह वहां कानूनी है क्योंकि x5 कॉन्स अभिन्न प्रकार का है जिसे प्रारंभ भी किया गया है।

+0

तो 'x2' एक वैश्विक var नहीं है जिसे एकाधिक '.cpp' फ़ाइलों के बीच साझा किया जा सकता है? – Alcott

+0

@ लचियनग्रिगोर: एक एकल अनुवाद इकाई में आप इसे 'const int ए :: x5;' (परिभाषा में प्रारंभिक प्रारंभ नहीं) के रूप में परिभाषित करते हैं। यदि आप यह सत्यापित करना चाहते हैं कि यह परिभाषा नहीं है तो प्रोग्राम में जोड़ें: 'void f (const int &) {} int main() {f (ए :: x5); } 'और आपको एक लिंकर त्रुटि मिलेगी (जब तक आप परिभाषा नहीं जोड़ते)। –

+0

@Alcott no, x2 प्रत्येक 'cpp' फ़ाइल के लिए अलग होगा। –

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