6

के साथ ऑब्जेक्ट्स के लिए प्रारंभकर्ता सूची क्या किसी प्रारंभिक सूची में क्लास सदस्य चर डालने का कोई लाभ है जिसे प्रारंभकर्ता सूची में होने की आवश्यकता नहीं है? उदाहरण:डिफ़ॉल्ट कन्स्ट्रक्टर

class Foo 
{ 
public: 
    Foo() {} 
}; 

class Bar 
{ 
public: 
    Bar() : _foo() {} 

private: 
    Foo _foo; 
}; 

क्या इस मामले में संकलक कुछ खास करता है?

+0

'_foo' पहले ही घोषणा' फू _foo से (foo के डिफ़ॉल्ट निर्माता का प्रयोग करके) प्रारंभ की है, 'आप फिर से inisialize को' का उपयोग _foo' 'बार() चाहते हैं: _foo (फू()) {} '। हालांकि, यह व्यर्थ होगा। – andre

+4

@ ओंडरसन: यह सही नहीं है। प्रारंभकर्ता सूची में '_foo' प्रारंभ किया गया है। यह एकमात्र ऐसा स्थान है जहां सदस्यों को कक्षा में शुरू किया जाता है। 'बार(): _foo (Foo()) {}' * * _foo' को फिर से शुरू नहीं करता है - यह ** ** इसे प्रारंभ करता है। –

+0

@ जॉन डीबलिंग ओह, मैं तब गलत था। मैं अब केरेक एसबी जवाब पढ़ने से समझता हूं। – andre

उत्तर

7

एक प्रारंभकर्ता सूची में एक निर्माता को प्रारंभ करने का पसंदीदा तरीका है। संदर्भ सदस्यों और निरंतर सदस्यों को प्रारंभ करने का यह एकमात्र संभव तरीका है।

इसके अलावा प्रारंभकर्ता सूची का उपयोग करके, प्रारंभ होने से पहले गलती से चर का उपयोग करने की संभावना को कम करता है। यह के बड़े दर्शन का हिस्सा है जो इसे प्रारंभ किए बिना एक चर परिभाषित करता है।

+0

यह ध्यान दिया जाना चाहिए कि सूची घोषणाओं के समान क्रम में होनी चाहिए। यह अच्छा अभ्यास है। –

+0

संदर्भ और निरंतर सदस्यों को कक्षा में प्रारंभिकरण (सी ++ 11) का उपयोग करके प्रारंभ किया जा सकता है।और प्रश्नों के प्रकार के लिए प्रारंभकर्ता सूची का कोई प्रभाव नहीं पड़ता है कि किसी सदस्य को प्रारंभ होने से पहले इसका उपयोग किया जा सकता है या नहीं; सदस्य दोनों मामलों में एक ही समय में डिफ़ॉल्ट रूप से प्रारंभ किया गया है। – bames53

+3

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

1

नहीं, इस मामले में कुछ भी अलग नहीं किया गया है। मुझे ऐसा करने का कोई फायदा नहीं दिख रहा है।

+0

लाभ यह है कि आप उन लोगों को भ्रमित नहीं करते हैं जिन्हें प्रारंभकर्ता सूचियों को देखने के लिए प्रशिक्षित किया गया है। – Cubic

+2

मुझे यकीन नहीं है कि इस तरह के प्रशिक्षण को पूरा करना एक अच्छा विचार है ... – bames53

6

जिन सदस्यों का उपयोग किया जा रहा है, कन्स्ट्रक्टर की प्रारंभकर्ता सूची में उल्लिखित सदस्य डिफ़ॉल्ट-प्रारंभिक नहीं हैं। Foo के लिए इसका मतलब है कि डिफ़ॉल्ट कन्स्ट्रक्टर को बुलाया जाएगा।

Bar() : _foo() { } और बिल्कुल नहीं Bar दे रही है एक स्पष्ट डिफ़ॉल्ट निर्माता (या Bar() = default कह रही है कि अपने संस्करण एक छोटी सी डिफ़ॉल्ट निर्माता नहीं है। इस प्रकार std::is_trivially_constructible<Bar>::value के मूल्यों यदि आप निर्माण ­ टो बाएं से अलग होगा के बीच का अंतर कुल मिलाकर बाहर है, हालांकि व्यवहार अन्यथा एक ही है।

+1

मुझे लगता है कि सवाल उपयोगकर्ता के बीच प्रारंभकर्ता सूची में प्रारंभकर्ता के साथ और बिना किसी निर्माता के बीच अंतर पर है, उपयोगकर्ता द्वारा प्रदान किए गए कन्स्ट्रक्टर और गैर-उपयोगकर्ता प्रदान किए गए कन्स्ट्रक्टर के बीच के अंतर पर नहीं। इस वास्तविक उत्तर के लिए – bames53

9

इस मामले में यह कोई फर्क नहीं पड़ता।

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

नोट: यदि आप उन्हें आंतरिककरण सूची में गलत क्रम में डालते हैं तो यह आमतौर पर अधिकांश कंपाइलरों पर एक चेतावनी है (जब तक आप चेतावनियों को त्रुटियों के रूप में संकलित नहीं करते हैं (जो आपको करना चाहिए)।

असली खतरा कक्षाओं के साथ है जिसमें पीओडी सदस्य और कंपाइलर उत्पन्न कन्स्ट्रक्टर है।

class NewFoo 
{ 
     int x; 
     int y; 
}; 
// Version 1: 
class Bar1 
{ 
    NewFoo f; 
}; 
// Version 2: 
class Bar2 
{ 
    NewFoo f; 
    public: 
     Bar2() // f not in list. 
     {} 
}; 
// Version 3: 
class Bar3 
{ 
    NewFoo f; 
    public: 
     Bar3() 
      : f() 
     {} 
}; 

int main() 
{ 
    Bar1  b1a;   // x and y not initialized. 
    Bar1  b1b = Bar1(); // x and y zero initialized. 
    Bar2  b2a;   // x and y not initialized. 
    Bar2  b2b = Bar2(); // x and y not initialized. 
    Bar3  b3a;   // x and y zero initialized. 
    Bar3  b3b = Bar3(); // x and y zero initialized. 
} 
+1

+1। मैं वर्षों से सलाह देने वाली शैली का अनुसरण कर रहा हूं, लेकिन अब मैं सोच रहा हूं कि सदस्यों की मामूली पुनरावृत्ति सिर्फ "शोर" हो सकती है। संरचना-जैसी कक्षाओं के लिए जिनके पास केवल डिफ़ॉल्ट कन्स्ट्रक्टर वाले सदस्य हैं, क्या खाली प्रारंभकर्ता सूची का उपयोग करना बेहतर नहीं होगा? – Wolf

+0

@ भेड़िया: हाँ। यह सभी प्रासंगिक है। आपको उस तकनीक का उपयोग करना चाहिए जो कोड को पढ़ने में आसान बनाता है। यदि यह स्पष्ट है कि आपकी कक्षा में ऐसे सदस्य हैं जो ऑटो निर्मित हैं तो बस खाली सूची होना ठीक है। –

+0

@Wolf: जानकारी के साथ अद्यतन उत्तर। –

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