2014-06-18 5 views
14

प्रारंभिक सूची आदेश कक्षा में परिवर्तनीय क्रम से मेल नहीं खाता है, तो जीसीसी ने अपना फिट क्यों फेंक दिया?आरंभकर्ता सूची आदेश सदस्य सदस्य घोषणा आदेश क्यों शुरू करना चाहिए?

class myClass 
{ 
public: 
    int A; 
    int B; 
    myClass(); 
}; 

myClass::myClass() : 
B(1), 
A(2) 
{} 

परिणाम देगा में:

file.h:274: warning: 'myClass::A' will be initialized after 
file.h:273: warning: 'int myClass::B 
file.cpp:581: warning: when initialized here 

कोई विशिष्ट कारण चेतावनी के इस प्रकार जारी किया जाता है है? क्या कक्षा के भीतर परिभाषित किए गए अलग-अलग क्रम में कक्षा के वैरिएबल को प्रारंभ करने से जुड़े कोई जोखिम हैं?

(ध्यान दें, वहाँ a question जो विषय को छू लेती है, लेकिन जवाब काफी हैं के बारे में कोई औचित्य दिए बिना ", क्योंकि यह होना चाहिए कि" क्यों यह आदेश दिया जाना चाहिए, या क्या इस से बाहर होने के साथ गलत क्या है आदेश - मैं जानना चाहता हूं कि ऐसा प्रतिबंध क्यों मौजूद है - क्या कोई ऐसा उदाहरण दे सकता है जहां यह संभवतः पीछे हट सकता है?)

+0

@ShafikYaghmour होगा: क्योंकि इस तरह के एक मौज है मानक प्रतिबंध नहीं है इसके लेखकों के। प्रत्येक प्रतिबंध कुछ विचारों का परिणाम है। तो, नहीं, "क्योंकि मानक इतना कहता है" अब तक पर्याप्त जवाब नहीं है। निश्चित रूप से मानक के कुछ निर्णय संदिग्ध, या सीधे गलत हो सकते हैं - लेकिन इन मुद्दों और गलतियों को भी कुछ उत्पत्ति से उत्पन्न होता है। –

+2

तो शायद आपका प्रश्न होना चाहिए "घोषणा का आदेश प्रारंभ करने का आदेश क्यों है?" चेतावनी के बारे में पूछने के बजाय। – dyp

+1

_ "क्या कोई विशिष्ट कारण है कि इस तरह की चेतावनी जारी की जाती है?" _ -एक कारण आपकी मदद करना है। –

उत्तर

13

चेतावनी उन परिस्थितियों को रोकने की कोशिश कर रही है जहां आप डेटा सदस्यों के गलत क्रम पर भरोसा कर सकते हैं।

myClass::myClass() : 
B(42), A(B) {} 

यहाँ, आप व्यवहार अपरिभाषित है क्योंकि आप एक गैर-आरंभिकृत B से पढ़ रहे हैं: क्या आपको लगता बी ए से पहले आरंभ नहीं हो जाता, और फिर आप कुछ इस तरह करते हैं कहो।

+0

यह _not_ प्रश्न का उत्तर देता है, क्योंकि _IF_ को किसी भी क्रम में प्रारंभिकरण [सूची] निर्दिष्ट करने की अनुमति थी, फिर आपने जो लिखा है, यानी बी से पहले बी, और बी के आधार पर ए, बस ठीक होगा। अनिवार्य रूप से आपने केवल हमें बताया है कि मानक कहता है कि गैर-स्थैतिक डेटा सदस्य प्रारंभिक निर्णय सदस्यों के घोषित किए जाने के क्रम में होता है, बिना किसी निर्णय के किसी तर्क के। –

+0

@DanielGoldfarb सवाल यह नहीं पूछ रहा है कि क्यों * मानक गैर स्थैतिक डेटा सदस्यों के एक निश्चित प्रारंभिक आदेश को निर्दिष्ट करता है। यह पूछ रहा है कि एक कार्यान्वयन एक निश्चित स्थिति में चेतावनी क्यों जारी करता है, और मैंने उस प्रश्न का उत्तर दिया है। – juanchopanza

+1

शायद मैं इसे गलत पढ़ रहा हूं। मुझे पता है कि सवाल संकलक चेतावनी के बारे में पूछना शुरू कर देता है, लेकिन इससे इसके लिए और भी कुछ है। "क्या कोई जोखिम है ... परिभाषित किए गए आदेश से अलग आदेश ..." और प्रश्न के अंत में "नोट" देखें, जो इंगित करता है कि मानक बताता है कि मानक के लिए तर्क नहीं देता है। आपका उत्तर _does_ चेतावनी के लिए एक तर्क देता है, और एक अच्छा बिंदु बनाता है; लेकिन ऐसा लगता है, यह जवाब नहीं देता है (प्रश्न के अंत में नोट उद्धृत करने के लिए) "इसे पहले क्यों आदेश दिया जाना चाहिए"। इम्हो, शाफिक यागहोर का जवाब और अधिक पूरा है। –

2

प्रारंभकर्ता सूची का क्रम मामला नहीं है। कक्षा शीर्षलेख में आपके सदस्यों की घोषणा प्रारंभिकरण आदेश को परिभाषित करती है।

यह डिज़ाइन और आवश्यक है क्योंकि आपके पास एकाधिक सीटीओआर पूरी तरह अलग सूची सूची ऑर्डर कर सकते हैं।

तो आपके सदस्य ALWAYS घोषणा के क्रम में आरंभ किए जाएंगे।

+0

* यह डिज़ाइन और आवश्यक * => है और यह एक मुद्दा क्यों है? ऐसा क्यों है कि प्रत्येक कन्स्ट्रक्टर सदस्य को क्रम में प्रारंभ नहीं कर सका? –

+0

http://stackoverflow.com/questions/4037219/order-of-execution-in-constructor-initialization-list देखें। चूंकि कई डिटर्स नहीं हैं, प्रारंभिकरण के उलट क्रम में डी-प्रारंभिकरण होना चाहिए। – Samuel

+1

मुझे पता है, मैं सिर्फ आपके उत्तर में "आवश्यक" के औचित्य को शामिल करने के लिए आपके उत्तर को संपादित करने में आपकी जांच कर रहा था। बीटीडब्ल्यू, यह पूरी तरह से मनमाना है; सी ++ ने एक स्पष्ट विकल्प बनाया कि विनाश आदेश * हमेशा * निर्माण आदेश के विपरीत होगा, और निर्माण आदेश को याद रखना उपयोगी समझा नहीं गया था (जो आपको आवश्यकता नहीं है + अलग संकलन मॉडल की आवश्यकता नहीं है), इस प्रकार दोनों निर्माण आदेश और विनाश आदेश तय कर रहे हैं। अन्य विकल्पों का इस्तेमाल किया जा सकता था। –

14

चेतावनी यह इंगित कर रही है कि आपके द्वारा कन्स्ट्रक्टर प्रारंभिक सूची में उपयोग किए जाने वाले आदेश के बावजूद मानक की आवश्यकता है कि गैर-स्थैतिक डेटा सदस्यों को घोषित किए गए क्रम में प्रारंभ किया जाए। हम draft C++ standard अनुभाग के लिए 12.6.2आरंभ किया जा रहा ठिकानों और सदस्यों पैरा जो कहते जाकर इस देख सकते हैं:

एक गैर सौंपने के निर्माता में, में प्रारंभ आय निम्न क्रम:

और इसमें शामिल हैं:

फिर, गैर स्थैतिक डेटा सदस्यों को क्रम में प्रारंभ किया गया था कक्षा परिभाषा में घोषित (फिर मेम-प्रारंभकर्ताओं के आदेश के बावजूद)।

मानक को इसकी आवश्यकता क्यों है?हम खंड 6 में कागज The Evolution of C++: 1985 to 1989 में इस के लिए एक औचित्य Bjarne Stroustrup द्वारा प्राप्त कर सकते हैं यह कहते हैं:

प्रारंभ सदस्यों से पहले प्रारंभ आधार वर्ग के साथ कक्षा में घोषणा के क्रम में जगह लेता है,

[ ...]

प्रारंभकर्ताओं के क्रम को अनदेखा करने का कारण कन्स्ट्रक्टर और विनाशक कॉल के सामान्य फीफो ऑर्डर को संरक्षित करना है। दो कंस्ट्रक्टर्स की अनुमति दे ठिकानों के प्रारंभ के विभिन्न आदेशों का उपयोग करने और सदस्यों कार्यान्वयन विवश अधिक गतिशील और अधिक महंगा रणनीतियों का उपयोग करने के लिए

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