2012-05-23 14 views
22

निम्नलिखित (सरलीकृत) स्थिति पर विचार करें:प्रारंभिक सूची में अन्य सदस्यों को आरंभ करने के लिए सदस्य चर का उपयोग किया जा सकता है?

class Foo 
{ 
private: 
    int evenA; 
    int evenB; 
    int evenSum; 
public: 
    Foo(int a, int b) : evenA(a-(a%2)), evenB(b-(b%2)), evenSum(evenA+evenB) 
    { 
    } 
}; 

जब मैं इस तरह फू instanciate:

Foo foo(1,3); 

तो evenA 0 है, evenB 2 है, लेकिन evenSum 2 के लिए शुरू किया जाएगा?

मैंने अपने वर्तमान प्लेटफ़ॉर्म (आईओएस) पर यह कोशिश की और ऐसा लगता है कि यह काम करता है, लेकिन मुझे यकीन नहीं है कि यह कोड पोर्टेबल है या नहीं।

आपकी मदद के लिए धन्यवाद!

+0

यह सी ++ में खतरनाक कोनों में से एक है। – iammilind

+0

कोडपैड ऐसी चीजों को देखने के लिए एक शानदार जगह है: http://codepad.org/uFgZpkwN –

+0

@Agent_L: यह आपको नहीं बताएगा कि कोड पोर्टेबल है या नहीं। –

उत्तर

27

यह अच्छी तरह से परिभाषित और पोर्टेबल, लेकिन यह संभावित रूप से त्रुटि-प्रवण है।

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


1. [class.base.init] से सी ++ मानक (रों) में:

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

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

मानक के इस खंड (हाइलाइटिंग मेरा है।)

तो अन्य सदस्य चर प्रारंभ करने में सदस्य चर उपयोग का एक उदाहरण देने के लिए चला जाता है।

+0

ठीक है तो अगर फू के पास बेस क्लास बार (गैर-आभासी सार्वजनिक विरासत) है और मैंने प्रारंभिक सूची में बार्स कन्स्ट्रक्टर डाला है, तो इसे हमेशा सभी सदस्य प्रारंभकर्ताओं के सामने निष्पादित किया जाएगा, भले ही मैं इसे प्रारंभिक सूची के अंत में रखूं? – Pontomedon

+0

@Pontomedon: हाँ। बेस क्लास कन्स्ट्रक्टर हमेशा पहले आते हैं (भले ही वे सूची में न हों)। –

6

सदस्यों को कक्षा परिभाषा में घोषित क्रम में आरंभ किया जाता है। जब तक आपकी प्रारंभिक सूची इस आदेश का पालन करती है, तब तक यह ठीक होना चाहिए।

0

यह भी जी ++ 4.0.3 (6 साल पुराना) पर त्रुटि के बिना संकलित किया गया।

मुझे विश्वास है कि यह किसी भी उचित हालिया कंपाइलर पर ठीक संकलित करेगा।

8

हां, प्रदान करें कि वे पहले से ही निर्मित किए जा चुके हैं। बस को न भूलें कि निर्माण का क्रम कक्षा परिभाषा, कन्स्ट्रक्टर में प्रारंभकर्ताओं के क्रम में घोषणाओं का क्रम है। और यह कि संकलक आमतौर पर आपको नहीं बताएगा कि क्या आप का निर्माण करने से पहले एक चर का उपयोग करते हैं। आपके मामले में, उदाहरण के लिए, यदि आप वर्ग के शीर्ष करने के लिए evenSum ले जाते हैं, आप व्यवहार अपरिभाषित है (क्योंकि इसके प्रारंभकर्ता अप्रारंभीकृत सदस्यों का उपयोग करता है), तब भी हालांकि अपने निर्माता में, आप प्रारंभ evenA और evenB lexically evenSum से पहले।

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

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