2013-08-28 6 views
21

मैं एक कठिन समय इस बात के लिए गूगल पर हिट पाने के आ रही है नाम नहीं बताती।सदस्य प्रारंभकर्ता एक गैर स्थिर डेटा के किसी सदस्य या आधार वर्ग

struct a { 
    float m_x; 
    float m_z; 
public: 
    a(float x): m_x(x) {} 
}; 

class b : public a { 
    b(float z): m_z(z) {} 
}; 

बजना 3.2 पर:

error: member initializer 'm_z' does not name a non-static data member or base class 
    b(float z): m_z(z) {} 
+0

क्यों? मैंने अभी तक "बुराई विरासत हीरा" नहीं बनाया है। @AndreyT उस प्रश्न में स्वीकृत उत्तर बेस सीटीआर बनाने के लिए कहता है। मेरे पास एक है ... ओह। मुझे लगता है कि मुझे बेस क्लास सीटीओ को कॉल करने की जरूरत है, सदस्य सीटीओ नहीं। ठीक। –

+0

@WhozCraig: यहां तक ​​कि अगर यह एक आभासी आधार है, यह अभी भी आप * अप्रत्यक्ष * सदस्यों को प्रारंभ नहीं दूँगा। वर्चुअल विरासत को अप्रत्यक्ष * आधार * के प्रारंभिकरण की आवश्यकता हो सकती है, लेकिन सदस्यों नहीं। – AnT

+1

@Steven लू: स्वीकार किए जाते हैं जवाब का कहना है कि 'एक :: m_z' केवल' A' के निर्माता प्रारंभकर्ता सूची से प्रारंभ किया जा सकता है। इसका उल्लेख 'बी' के कन्स्ट्रक्टर प्रारंभकर्ता सूची में नहीं किया जा सकता है (जैसा कि आपके कोड में है)।भाषा उस अनुमति नहीं देता है। यही तो बात है। अर्थात। आपको 'm_z' के लिए विशिष्ट रूप से' a' के कन्स्ट्रक्टर में एक और पैरामीटर जोड़ना होगा (जैसा आपने 'm_x' के लिए किया था) और उस कन्स्ट्रक्टर के माध्यम से प्रारंभिक मान' b' से पास करें। बीटीडब्लू, ऊपर दिए गए आपके कोड में आपको 'बी' के निर्माता से 'ए' के कन्स्ट्रक्टर का संदर्भ देना होगा। अन्यथा, यह संकलित नहीं होगा, क्योंकि आपके पास 'a' में कोई डिफ़ॉल्ट कन्स्ट्रक्टर नहीं है। – AnT

उत्तर

26

नहीं आप प्रारंभकर्ता सूची सीधे से आधार वर्ग के सदस्यों को प्रारंभ नहीं कर सकता है। इसका कारण यह है इस तरह से प्रारंभ आय का आदेश

सी ++ स्टैंडर्ड n3337 § 12.6.2/10

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

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

- फिर, प्रत्यक्ष आधार वर्ग घोषणा के क्रम में प्रारंभ कर रहे हैं के रूप में वे (चाहे मेम-initializers के आदेश के) आधार विनिर्देशक-सूची में दिखाई देते हैं।

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

- अंत में, कन्स्ट्रक्टर बॉडी के कंपाउंड-स्टेटमेंट को निष्पादित किया गया है।

[नोट: घोषणा के क्रम में आधार है और सदस्य subobjects आरंभीकरण के विपरीत क्रम में नष्ट कर रहे हैं सुनिश्चित करने के लिए अनिवार्य है। - अंत टिप्पणी]

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

पूर्व मामले में आप इसे इस तरह लिख सकते हैं:

struct A { 
    float m_x; 
    float m_z; 
    A(){} 
protected: 
    A(float x): m_x(x) {} 
}; 

class B : public A { 
public: 
    B(float z) : A(z) {} 
    // alternatively 
    // B(float z) { 
    //  m_x = z; 
    // } 
}; 

int main(){ 
    B b(1); 
    return 0; 
} 
संबंधित मुद्दे