2013-04-17 9 views
7

सी ++ कक्षाओं के साथ, आप एक व्युत्पन्न कक्षा को अपने मूल वर्ग से एक चर का उत्तराधिकारी प्राप्त कर सकते हैं। मैं व्युत्पन्न कक्षा को कैसे परिभाषित कर सकता हूं ताकि var2derivclass में विरासत में नहीं मिला हो?सी ++ कक्षाओं में एक चर का उत्तराधिकारी कैसे प्राप्त करें

class mainclass{ 
public: 
    int var1; 
    char var2; 
    void test(){ 
     cout<<var1<<var2<<endl; 
    } 
} 
class derivclass : mainclass{ 
public: 
    void test(){ 
     cout<<var1<<var2<<endl; 
     //want a compiler error here that var2 is not defined 
    } 
} 
+3

यह 'private' करें। यदि सदस्य 'सार्वजनिक' है तो आप विरासत से बच नहीं सकते हैं। –

+4

यदि आप इसे 'मेनक्लास' में 'निजी' के रूप में परिभाषित करते हैं, तो 'डेरिवक्लास' इसे स्पर्श करने में सक्षम नहीं होगा, लेकिन यह अभी भी * मौजूद होगा * – Dave

+0

निजी कीवर्ड करेगा। –

उत्तर

7

सी ++ में विरासत में मिला जा रहा से एक सदस्य को रोकने के लिए विहित जिस तरह से यह private घोषित करने के लिए है। व्युत्पन्न कक्षाएं जो इसे एक्सेस करने का प्रयास करती हैं, फिर एक कंपाइलर त्रुटि फेंक देंगी। यह इस तरह दिखेगा:

class mainclass{ 
public: 
    int var1; 
    void test(){ 
     cout<<var1<<var2<<endl; 
    } 
private: 
    char var2; 
} 
class derivclass : mainclass { 
    public: 
    void test(){ 
     cout<<var1<<var2<<endl; 
     //compiler error here; var2 is not accessible 
    } 
} 

इस लक्ष्य को हासिल करने के लिए आप क्या कह रहे हैं सबसे सरल तरीका है।

+2

मुझे लगता है कि आपके उदाहरण में आपके पास 'var1' और' var2' उलट है। आपके उदाहरण में 'var1' पहुंच योग्य नहीं होगा। –

+0

आह ठीक है, धन्यवाद। प्वाइंट है कि मैं 'मेनक्लास' के बाहर से उपलब्ध गैर-विरासत चर बनाना चाहता हूं। यदि मैं गेटटर और सेटर को 'इनलाइन' के रूप में परिभाषित करता हूं, तो क्या वह ओवरहेड को प्रेरित करेगा? – tomsmeding

+0

@tomsmeding: तो आप * 'derivclass' को छोड़कर वैरिएबल को' mainclass' से बाहर * सभी तक पहुंचा सकते हैं? मुझे नहीं लगता कि यह संभव है; यदि कोई सदस्य सार्वजनिक है, या सार्वजनिक गेटटर है, तो हर कोई व्युत्पन्न कक्षाओं सहित इसका उपयोग कर सकता है। या यह आपकी आवश्यकताओं को पूरा करेगा यदि व्युत्पन्न वर्ग परिवर्तनीय तक पहुंच सकता है लेकिन केवल गेटर के माध्यम से? – Edward

4

आप इसे private बना सकते हैं। लेकिन आपको शायद नहीं करना चाहिए।

तथ्य यह है कि इसे आधार से कुछ सामानों का उत्तराधिकारी नहीं होना चाहिए इसका मतलब है कि शायद इसे बेस से सीधे प्राप्त नहीं करना चाहिए।

इसके बजाय एक और बेस क्लास बनाएं और दो वर्गों को उस आधार से प्राप्त करें।

class Baseclass{ 
public: 
    void test(){ 
     cout<<var1<<endl; 
    } 
protected: 
    int var1; 

} 

class mainclass : public Baseclass{ 
public: 
    char var2; 
    void test(){ 
     cout<<var1<<var2<<endl; 
    } 
} 

class derivclass : Baseclass{ 
public: 
    void test(){ 
     cout<<var1<<endl; 
    } 
} 
+0

यदि आप नीचे मतदान करते हैं तो कृपया कम से कम उल्लेख करने के लिए सौजन्य रखें। – stardust

+0

मैं आपको एक बिंदु वापस दे दूंगा क्योंकि आपका जवाब ठीक है। पता नहीं क्यों किसी ने इसे वोट दिया। –

+1

मैंने आपके उत्तर को वोट नहीं दिया है, लेकिन सबसे अच्छी बात यह है कि हमेशा अपने डेटा सदस्यों को निजी बनाएं, और आवश्यकतानुसार गेटर्स और सेटर्स को परिभाषित करें। स्कॉट मेयर्स द्वारा "प्रभावी सी ++" देखें। – Dima

2

जैसा कि हर कोई कहता है, आप इसे बेस क्लास में निजी बना सकते हैं और फिर यह किसी भी उप-वर्ग में पहुंच योग्य नहीं है। हालांकि, जैसा कि @ डेव कहते हैं, यह अभी भी बेस क्लास के अंदर मौजूद होगा। यदि आप यह भी नहीं चाहते हैं कि यह एक चर के रूप में मौजूद हो जो सबक्लास से छिपा हुआ है, तो आपको इसे बेस क्लास से बाहर ले जाना होगा। यह मानते हुए कि किसी चीज़ के लिए चर की आवश्यकता है, तो आपको उस नए उप-वर्ग को बनाना होगा जिसमें वह चर शामिल है।

0

एक व्युत्पन्न वर्ग अपने अड्डों के प्रत्येक सदस्य को विरासत में लेता है। पूर्ण विराम। आप आधार वर्ग के कुछ हिस्सों का चयन नहीं कर सकते हैं।

एक परिवर्तनीय निजी बनाना विरासत को रोकता नहीं है। चर स्थिर है, लेकिन सामान्य परिस्थितियों में यह सुलभ नहीं है। विभिन्न दोस्ती खेलों के साथ आप इसे सुलभ बना सकते हैं। यहां भ्रम का हिस्सा जावा के कारण होता है, जहां निजी सदस्यों को विरासत में नहीं मिला है। यही कारण है,

struct Base { 
private: 
    int i; 
}; 

struct Derived : Base { 
}; 

Derived d; 
d.i = 3; // error: d.i is not accessible 

तो i विरासत में मिला नहीं था, त्रुटि होगा d कोई भी सदस्य i नामित किया है।

संपादित करें: एक और, शायद और अधिक सार्थक, उदाहरण के

void f(); 

class Base { 
    void f(); 
}; 

class Derived : Base { 
    void g() { 
     f(); // error: Base::f is not accessible 
}; 

जावा के नियमों के साथ, f() करने के लिए कॉल उचित रहेगा, और वैश्विक f() कहेंगे।

+0

@ कोनराड रुडॉल्फ - उह, कुछ भी नहीं। आप क्या? –

+0

अच्छी तरह से यह सुनिश्चित नहीं है कि आप यह विचार कैसे प्राप्त कर रहे हैं कि जावा विरासत में सदस्यों को जादुई रूप से हटा सकता है। निश्चित रूप से जावा में एक व्युत्पन्न वर्ग * सभी * इसके आधार के सदस्यों को विरासत में मिला है। –

+0

@ कोनराड रुडॉल्फ - मैंने यह नहीं कहा कि विरासत में यह जादुई रूप से सदस्यों को हटा सकता है। –

0

अन्य सभी उत्तरों (और संभवतः स्टोकास्टिक रूप से बंद होकर) के जवाब में, आप मुख्य और व्युत्पन्न वर्ग को स्विच कर सकते हैं, जहां नए मुख्य वर्ग में सभी सदस्य मूल्य होंगे जो आप मूल व्युत्पन्न वर्ग में चाहते हैं नई व्युत्पन्न वर्ग में अनावश्यक लोगों (मूल मुख्य वर्ग उर्फ)

का निरीक्षण करें:

class newMainClass{ 
public: 
    int var1; 
    virtual void test(){ //added virtual here so there aren't two definitions for test() 
     cout<<var1<<var2<<endl; 
     //want a compiler error here that var2 is not defined 
    } 
} 

class newDerivedClass : public newMainClass{ 
public: 
    char var2; 
    void test(){ 
     cout<<var1<<var2<<endl; 
    } 
} 
+0

मुझे "बॉक्स के बाहर" सोच पसंद है, लेकिन यह वास्तव में एक समाधान नहीं है। इसके बजाय, यह समस्या से बचने का एक तरीका है। विरासत संबंध को उलटना हमेशा संभव नहीं होता है। – Julian

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