2010-11-17 10 views
44

मैं C++ निम्नलिखित वर्ग परिभाषाएं हैं:सी ++ कक्षा की आरंभकर्ता सूची में सदस्य-संरचना कैसे शुरू करें?

struct Foo { 
    int x; 
    char array[24]; 
    short* y; 
}; 

class Bar { 
    Bar(); 

    int x; 
    Foo foo; 
}; 

और "foo" struct बार वर्ग के प्रारंभकर्ता में शून्य करने के लिए (अपने सभी सदस्यों के साथ) को प्रारंभ करना चाहते हैं। क्या यह इस तरह से किया जा सकता है:

Bar::Bar() 
    : foo(), 
    x(8) { 
} 

...?

या शुरुआती सूची में foo (x) क्या करता है?

या संरचना भी संकलक से स्वचालित रूप से शून्य में शुरू हो गई है?

+3

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

उत्तर

49

सबसे पहले, आपको पीओडी और समेकन के संबंध में यह c++ faq पढ़ना चाहिए (चाहिए!) आपके मामले में, Foo वास्तव में एक पॉड वर्ग है और foo() एक मूल्य प्रारंभ है: प्रकार का एक उद्देश्य मूल्य आरंभ कर

करने के लिए टी का अर्थ है:

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

तो हाँ, foo शून्य से आरंभ हो जाएगा। ध्यान दें कि यदि आप Bar निर्माता से प्रारंभ हटा दिया, foo केवल होगा डिफ़ॉल्ट-प्रारंभ: कोई प्रारंभकर्ता एक वस्तु के लिए निर्दिष्ट किया जाता है, और वस्तु की (संभवतः सीवी-योग्य) गैर है

हैं -पीओडी कक्षा प्रकार (या सरणी), ऑब्जेक्ट डिफ़ॉल्ट-प्रारंभिक होगा; यदि ऑब्जेक्ट कॉन्स-क्वालिफाइड प्रकार का है, अंतर्निहित कक्षा प्रकार में उपयोगकर्ता द्वारा घोषित डिफ़ॉल्ट कन्स्ट्रक्टर होगा। अन्यथा, यदि कोई प्रारंभकर्ता एक nonstatic वस्तु, वस्तु और उसके subobjects के लिए निर्दिष्ट किया है, यदि कोई हो, एक अनिश्चित प्रारंभिक मूल्य है;

+2

में गैर-कुल (ctor) का उपयोग नहीं कर सकते हैं क्या होगा अगर foo एक के रूप में परिभाषित किया गया था कॉन्स सदस्य? – RezaPlusPlus

8

मानक सी ++ में आपको फू के लिए एक सीटीआर बनाने की आवश्यकता है।

struct Foo { 

    Foo(int const a, std::initializer_list<char> const b, short* c) 
    : x(a), y(c) { 
    assert(b.size() >= 24, "err"); 
    std::copy(b.begin(), b.begin() + 24, array); 
    } 

    ~Foo() { delete y; } 

    int x; 
    char array[24]; 
    short* y; 
}; 

class Bar { 

    Bar() : x(5), foo(5, {'a', 'b', ..., 'y', 'z'}, 
    new short(5)) { } 

    private: 

    int x; 
    Foo foo; 
}; 

C++ 0x आप वर्दी प्रारंभ सूची का उपयोग कर सकते हैं, लेकिन अभी भी आप कम महत्वपूर्ण चीज़ों के लिए dtor की जरूरत है:

class Bar { 

    Bar() : x(5), foo{5, new char[24]{'a', 'b', ..., 'y', 'z'}, 
    new short(5)} { } 
    ~Bar() { delete[] foo.array; delete foo.y;} 
    } 
    private: 

    int x; 
    Foo foo; 
}; 

डिफ़ॉल्ट करने के लिए प्रारंभ foo (Bar() : foo(), x(8) { } के रूप में) आप कम महत्वपूर्ण चीज़ों एक डिफ़ॉल्ट ctor देने की आवश्यकता ।

+2

यह थोड़ा अस्पष्ट है जहां आप सी ++ 03 बनाम सी ++ 0x का उपयोग करते हैं। आईआईआरसी 'प्रारंभकर्ता_सूची' सी ++ 0x का हिस्सा है। आपके दूसरे कोडब्लॉक में इसके अलावा आपने दो मेमोरी लीक बनाए हैं। –

+0

@Fabio: उनका कहना है कि बाहर के लिए धन्यवाद, संपादित – erjot

+0

अब आप 'नए चार से एक डबल विलोपन (' foo.y') और एक स्मृति रिसाव है ([24] ', इसके अलावा, मुझे नहीं यकीन है (लेकिन मैं हो सकता है गलत यहाँ) है कि इस तरह से 'उपयोग करने के लिए initializer_list') –