2010-02-18 10 views
111

के साथ अभिभावक के संरक्षित सदस्यों को आरंभ करें क्या माता-पिता वर्ग में संरक्षित डेटा सदस्यों को आरंभ करने के लिए बाल वर्ग के निर्माता की आरंभिक सूची का उपयोग करना संभव है? मैं इसे काम नहीं कर सकता। मैं इसके चारों ओर काम कर सकता हूं, लेकिन अगर मुझे ऐसा नहीं करना अच्छा लगेगा।आरंभिक सूची (सी ++)

कुछ नमूना कोड:

class Parent 
{ 
protected: 
    std::string something; 
}; 

class Child : public Parent 
{ 
private: 
    Child() : something("Hello, World!") 
    { 
    } 
}; 

जब मैं यह कोशिश, संकलक मुझसे कहता है: "वर्ग 'बाल' किसी भी क्षेत्र 'कुछ' नामित नहीं है"। क्या ऐसा कुछ संभव है? यदि हां, तो वाक्यविन्यास क्या है?

बहुत धन्यवाद!

उत्तर

103

आपके वर्णन के तरीके में यह संभव नहीं है। आपको इसे आगे बढ़ाने के लिए बेस क्लास में एक कन्स्ट्रक्टर (संरक्षित किया जा सकता है) जोड़ना होगा।

class Parent 
{ 
protected: 
    Parent(const std::string& something) : something(something) 
    {} 

    std::string something; 
} 

class Child : public Parent 
{ 
private: 
    Child() : Parent("Hello, World!") 
    { 
    } 
} 
+2

यह ठीक तरीके को मैं पहले से ही के साथ आने होता है "का उपयोग" की कोशिश कर सकते हैं। कम से कम अब मुझे चिंता करने की ज़रूरत नहीं है कि यह किया जा सकता है या नहीं। :) – Stephen

11

आप व्युत्पन्न वर्ग निर्माता प्रारंभ सूची में माता पिता के वर्ग के सदस्यों प्रारंभ नहीं कर सकते हैं: की तरह। इससे कोई फर्क नहीं पड़ता कि वे सुरक्षित हैं, सार्वजनिक हैं या कुछ और।

अपने उदाहरण में, सदस्य somethingParent वर्ग है, जिसका अर्थ है कि यह केवल Parent वर्ग के निर्माता प्रारंभकर्ता सूची में प्रारंभ किया जा सकता है के सदस्य है।

51

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

C++ 0x मसौदा:

12.6.2 आरंभ किया जा रहा ठिकानों और सदस्यों एक सदस्य-प्रारंभकर्ता-आईडी में

नाम के दायरे में ऊपर देखा जाता है कन्स्ट्रक्टर की कक्षा और, यदि उस क्षेत्र में नहीं मिला है, तो स्कोप में देखा गया है जिसमें कन्स्ट्रक्टर की परिभाषा है। [नोट: यदि निर्माता की क्लास एक प्रत्यक्ष या वर्ग के आभासी आधार वर्ग, एक मेम-प्रारंभकर्ता-आईडी सदस्य या आधार वर्ग नामकरण और एक एकल पहचानकर्ता से बना संदर्भित करता है के रूप में एक ही नाम के साथ एक सदस्य शामिल कक्षा के सदस्य के लिए। छुपा बेस क्लास के लिए एक meminitializer- आईडी योग्य नाम का उपयोग करके निर्दिष्ट किया जा सकता है। अंत टिप्पणी] मेम-प्रारंभकर्ता-आईडी के नाम जब तक निर्माता की क्लास, एक गैर स्थिर डेटा निर्माता के वर्ग के सदस्य या उस वर्ग के एक सीधा या आभासी आधार, मेम-प्रारंभकर्ता बीमार का गठन है ।

नोट: जोर मेरा।

+2

मुझे "क्यों" पर इंगित करने के लिए धन्यवाद। कुल समझ में आता है। मैं बहुत लंबे समय से सी ++ से दूर गया हूं ... :) – Stephen

0

हो सकता है कि आप इसे इस तरह से कीवर्ड का उपयोग

class Parent 
{ 

protected: 
std::string something; 
}; 

class Child : public Parent 
{ 

private: 
using Parent::something; 
Child() 
{ 
    something="Hello, World!"; 
} 
}; 
संबंधित मुद्दे