2009-08-13 15 views

उत्तर

79

यह एक प्रारंभ सूची है, और निर्माता के कार्यान्वयन का हिस्सा है: - अपने उदाहरण में, यह नहीं बल्कि कुछ इस तरह (यह सभी मामलों में बराबर है मतलब यह नहीं है कुछ इस तरह) है।

निर्माता के हस्ताक्षर है:

MyClass(); 

इसका मतलब है कि निर्माता कोई पैरामीटर के साथ कहा जा सकता है। यह इसे डिफ़ॉल्ट कन्स्ट्रक्टर बनाता है, यानी, जब आप MyClass someObject; लिखते हैं तो डिफ़ॉल्ट रूप से कॉल किया जाएगा।

भाग : m_classID(-1), m_userdata(0) को प्रारंभिक सूची कहा जाता है। यह आपकी पसंद के मूल्यों के साथ आपकी ऑब्जेक्ट के कुछ फ़ील्ड (यदि आप चाहते हैं) को प्रारंभ करने का एक तरीका है, तो उन्हें अपरिभाषित के रूप में छोड़ने के बजाय।

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

2

यह प्रारंभिक सूची की शुरुआत को दर्शाता है, जो आपके ऑब्जेक्ट के सदस्य चर शुरू करने के लिए है।

के रूप में: MyClass(m_classID = -1, m_userdata = 0);

एक निर्माता जो तर्क ले सकते घोषणा करता है कि (इसलिए मैं एक MyClass का उपयोग कर MyClass m = MyClass(3, 4), जिसमें m_classID जा रहा है 3, और m_userdata जा रहा है 4 परिणाम होगा बना सकते हैं)। अगर मुझे MyClass कन्स्ट्रक्टर में कोई तर्क नहीं दिया गया, तो इसके परिणामस्वरूप प्रारंभिक सूची के साथ संस्करण में समकक्ष वस्तु बन जाएगी।

0

इस मामले में: हाँ, आईएसटी बराबर है क्योंकि केवल आदिम प्रकारों का संबंध है।

यदि सदस्य कक्षाएं (structs) हैं तो आपको प्रारंभिक सूची पसंद करनी चाहिए। ऐसा इसलिए है क्योंकि अन्यथा ऑब्जेक्ट्स डिफ़ॉल्ट रूप से निर्मित होते हैं और फिर असाइन किए जाते हैं।

1

यह initialization list है।


class MyClass { 

public: 

    MyClass(){ 
     m_classID = -1; 
     m_userdata = 0; 
    } 

    int m_classID; 
    void *m_userdata; 

};
2

यह प्रारंभकर्ता सूची की शुरुआत को संकेत देता है।

यह भी MyClass (m_classId = -1, m_userData = 0) के बराबर नहीं है। यह एक पैरामीटर को परिभाषित करने का प्रयास कर रहा है जिसमें 2 पैरामीटर हैं जिनके पास डिफ़ॉल्ट मान हैं। हालांकि मूल्यों में कमी की कमी है और इसे बिल्कुल संकलित नहीं करना चाहिए।

1

इसे सदस्य प्रारंभिक सूची कहा जाता है। इसका उपयोग सुपरक्लास कंसट्रक्टर को कॉल करने के लिए किया जाता है, और आपके सदस्य चर को उनके द्वारा बनाए गए समय पर प्रारंभिक मान देता है।

इस मामले में, यह m_classID से -1 और m_userData को न्यूल में प्रारंभ कर रहा है।

यह कन्स्ट्रक्टर के शरीर में असाइन करने के बराबर नहीं है, क्योंकि बाद वाला सदस्य सदस्य चर बनाता है, फिर उन्हें असाइन करता है। प्रारंभिकरण के साथ, प्रारंभिक मूल्य सृजन के समय प्रदान किया जाता है, इसलिए जटिल वस्तुओं के मामले में, यह अधिक कुशल हो सकता है।

+1

यह भी कभी कभी उपयोग करने के लिए बहुत जरूरी है सदस्य प्रारंभिक सूची। यदि आपके पास सदस्य चर है जो संदर्भ है तो आपको इसे सदस्य प्रारंभिक सूची का उपयोग करके सेट करना होगा। – Skurmedel

1

यह बिल्कुल एक ऑपरेटर नहीं है। यह एक निर्माता के लिए वाक्यविन्यास का एक हिस्सा है।

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

लगातार सदस्यों को इस तरह से प्रारंभ करना होगा। गैर-स्थिरांक भी यहां प्रारंभ किए जा सकते हैं, जब तक कि यह एक अभिव्यक्ति के साथ किया जा सके। यदि सदस्य को प्रारंभ करने के लिए उससे अधिक कोड लेता है, तो आपको इसे करने के लिए {} के बीच वास्तविक कोड रखना होगा।

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

1

इसकी प्रारंभिक सूची की शुरुआत जो ऑब्जेक्ट के निर्माण के दौरान सदस्य चर सेट करती है। आपका उदाहरण "MyClass (m_classID = -1, m_userdata = 0);" के रूप में आप सही निर्माता निर्धारित नहीं किया है और तुम वैसे भी पैरामीटर सूची में सदस्य चर का उपयोग करने के लिए सक्षम नहीं होगा संभव नहीं है ... आप की तरह कुछ हो सकता था:

MyClass(int classId = -1, void* userData = 0) : m_classID(classId), m_userdata(userData) {} 

initialiser सूची की तुलना में बेहतर माना जाता है :

MyClass(int classId = -1, void* userData = 0) { 
    m_classID = classId; 
    m_userdata = userData; 
} 

अधिक जानकारी के लिए Google।

37

यह एक प्रारंभिक सूची है।

जब तक आप निर्माता के शरीर में जाते हैं, तब तक सभी क्षेत्रों का निर्माण किया जा चुका है; अगर उनके पास डिफॉल्ट कन्स्ट्रक्टर हैं, तो उन्हें पहले से ही बुलाया गया था। अब, यदि आप कन्स्ट्रक्टर के शरीर में उन्हें एक मान निर्दिष्ट करते हैं, तो आप प्रतिलिपि असाइनमेंट ऑपरेटर को कॉल कर रहे हैं, जिसका अर्थ हो सकता है कि ऑब्जेक्ट के पास संसाधनों को छोड़ना और पुनः प्राप्त करना (उदा। स्मृति) हो सकता है।

तो int जैसे प्राचीन प्रकार के मामले में, उन्हें कन्स्ट्रक्टर के शरीर में निर्दिष्ट करने की तुलना में कोई फायदा नहीं होता है। ऑब्जेक्ट्स के मामले में जिसमें कन्स्ट्रक्टर होता है, यह एक प्रदर्शन अनुकूलन है क्योंकि यह एक के बजाय दो ऑब्जेक्ट प्रारंभिकताओं से गुजरता है।

यदि फ़ील्ड में से कोई एक संदर्भ है तो एक प्रारंभिक सूची आवश्यक है क्योंकि संदर्भ कभी भी शून्य नहीं हो सकता है, यहां तक ​​कि ऑब्जेक्ट निर्माण और कन्स्ट्रक्टर के शरीर के बीच संक्षिप्त समय में भी नहीं। निम्नलिखित त्रुटि C2758 को जन्म देती है: 'MyClass :: member_': निर्माता आधार/सदस्य प्रारंभकर्ता सूची में प्रारंभ किया जाना चाहिए

class MyClass { 
public : 
    MyClass(std::string& arg) { 
     member_ = arg; 
    } 
    std::string& member_; 
}; 

केवल सही तरीका है:

class MyClass { 
public : 
    MyClass(std::string& arg) 
     : member_(arg) 
    { 
    } 
    std::string& member_; 
}; 
+2

अक्सर यह गलत माना जाता है कि यदि आपके पास संदर्भ सदस्य है, तो आपके पास * कन्स्ट्रक्टर प्रारंभकर्ता सूची के साथ एक कन्स्ट्रक्टर को परिभाषित करने के लिए * है।लेकिन यह काफी सच नहीं है। एक सरल 'MyClass m = {arg};' ठीक काम करेगा। –

+0

litb: लेकिन फिर आप m = {arg} का उपयोग करने के लिए कम या ज्यादा आवश्यक हैं; क्या तुम नहीं हो मेरी आंखों में, MyClass एम (रेफरी) करने में सक्षम होना काफी वांछित है। – Skurmedel

+0

@ स्कुरमेडेल, मैं सहमत हूं। लेकिन इसका मतलब यह नहीं है कि यह करने का एकमात्र तरीका है। –

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