2009-08-21 16 views
6
struct A { 
    static const int a = 5; 

    struct B { 
     static const int b = a; 
    }; 

}; 

int main() { 
    return A::B::b; 
} 

उपरोक्त कोड संकलित करता है। हालांकि यदि आप स्कॉट मायर्स द्वारा प्रभावी सी ++ पुस्तक द्वारा जाते हैं (पृष्ठ 14); हमें घोषणा के अलावा एक परिभाषा की आवश्यकता है। क्या कोई यह समझा सकता है कि यह अपवाद क्यों है?संरचना/कक्षा

+1

कोड _does_ में 'ए' के ​​लिए परिभाषा है। –

+2

नहीं, इसमें कोई परिभाषा नहीं है। –

+1

@ हेंक। ज़रुरी नहीं। एक समारोह में 'ए' या 'बी' के पते को पारित करने का प्रयास करें और देखें कि कंपाइलर कौन सा संदेश उत्पन्न करता है! –

उत्तर

18

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

अन्य वैरिएबल प्रकार (जैसे स्थिर स्थिरांक चार * के रूप में) आम तौर पर जहां वे घोषित किया गया है परिभाषित नहीं किया जा सकता, और एक अलग परिभाषा की आवश्यकता है।

एक छोटा सा अधिक विवरण के लिए, पता है कि एक वैश्विक चर तक पहुँचने आम तौर पर निचले स्तर कोड में कोई पता संदर्भ बनाने की आवश्यकता है। लेकिन आपका ग्लोबल वैरिएबल एक पूर्णांक है जिसका आकार आमतौर पर किसी पते के आकार के आसपास होता है, और संकलक को पता चलता है कि यह कभी नहीं बदलेगा, तो पॉइंटर अमूर्तता को जोड़ने में परेशानी क्यों है?

+0

+1, अच्छा जवाब। लेकिन क्या होगा यदि 'const' integers? क्या हम कक्षा में अपना मूल्य निर्दिष्ट कर सकते हैं? – Alcott

+0

"पूर्णांक" नहीं, केवल निरंतर अभिव्यक्ति – czxyl

18

वास्तव में पंडिताऊ नियमों के अनुसार, हाँ, अपने कोड है कि स्थिर पूर्णांक के लिए एक परिभाषा की जरूरत है। लेकिन व्यावहारिक नियमों के अनुसार, और सभी कंपाइलर क्या कार्यान्वित करते हैं क्योंकि इस प्रकार सी ++ 03 के नियम इरादे से हैं - नहीं, आपको परिभाषा की आवश्यकता नहीं है।

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

अपनी वापसी बयान में सदस्य के मान तुरंत, पढ़ने के लिए है ताकि आप स्थिर निरंतर पूर्णांक सदस्य की परिभाषा यह है कि अगर इसके बारे में केवल फायदा नहीं है मिटा सकते हैं। निम्नलिखित स्थिति, एक परिभाषा की जरूरत है, लेकिन:

struct A { 
    static const int a = 5; 

    struct B { 
     static const int b = a; 
    }; 

}; 

int main() { 
    int *p = &A::B::b; 
} 

कोई मूल्य यहाँ पढ़ रहा है - लेकिन बजाय इसके बारे में पता लिया जाता है। इसलिए, सी ++ 03 मानक का इरादा यह है कि आपको कुछ कार्यान्वयन फ़ाइल में निम्न जैसे सदस्य की परिभाषा प्रदान करनी है।

const int A::B::b; 

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

C++ 0x के शब्दों है कि दोष रिपोर्ट संकल्प शामिल करने के लिए, और के रूप में लिखा अपने कोड अनुमति देने के लिए अद्यतन किया गया है।

+0

क्या इसका मतलब है कि वॉल्ट डब्ल्यू गलत है जब वह कहता है: "सी ++ कंपाइलर्स स्थैतिक कॉन्स पूर्णांक (और केवल पूर्णांक) को उनके द्वारा घोषित स्थान पर परिभाषित करने की अनुमति देते हैं"? मैंने उसके जैसे सोचा कि "स्थिर कॉन्स int = 5;" बयान दोनों घोषणा और परिभाषा थी। अगर मैं सही ढंग से समझता हूं, तो यह केवल किसी भी परिभाषा के बिना एक घोषणा है और ए :: ए केवल बहुत विशिष्ट मामलों में उपयोग किया जा सकता है। मैं अंतिम शब्द में intesrested हूँ ... – neuro

+0

हाँ, वह भी गलत है। यह केवल एक घोषणा है - यह एक परिभाषा नहीं है। यदि आप उन मामलों में संदर्भित करते हैं जो तुरंत मूल्य नहीं पढ़ते हैं, तो एक परिभाषा की आवश्यकता होती है। आपको लगता है कि यह आपकी टिप्पणी में सही है। –

+0

बेहतर? मुझे लगता है कि यह "परिभाषा" का तकनीकी उपयोग नहीं था –

0

सामान्य में, सबसे अधिक (और हाल ही में) सी ++ compilers स्थिर स्थिरांक ints

तुम सिर्फ भाग्यशाली है, शायद नहीं देते हैं। पुराने कंपाइलर का प्रयास करें, जैसे जीसीसी 2.0 और यह आपको कम से कम त्रुटि संदेश के साथ जोरदार रूप से दंडित करेगा।

1

हालांकि, अगर आप "को परिभाषित करने" के बिना त्रिगुट संकार्य कोशिश स्थिर consts, आप एक लिंकर त्रुटि जीसीसी 4x में मिलता है:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13795

इसलिए, भले ही int k = A::CONSTVAL; तरह निर्माणों वर्तमान मानक में अवैध हैं, वे समर्थित हैं। लेकिन टर्नरी ऑपरेंड नहीं है। यदि आप मेरी बहाव प्राप्त करते हैं तो कुछ ऑपरेटर दूसरों के मुकाबले अधिक समान होते हैं :)

"लक्स" नियमों के लिए बहुत कुछ। मेरा सुझाव है कि यदि आप आश्चर्य नहीं चाहते हैं तो आप मानक के अनुरूप कोड लिखते हैं।

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

  • कोई संबंधित समस्या नहीं^_^