c++ questions कैसे सार्वजनिक रूप से एक आधार वर्ग से विरासत में मिली है, लेकिन कुछ सार्वजनिक तरीकों को आधार वर्ग निजी से व्युत्पन्न वर्ग में बनाते हैं?



c++ programs (6)

उदाहरण के लिए, क्लास Base के दो सार्वजनिक तरीके हैं: foo() और bar() । वर्ग Derived वर्ग Base से विरासत में मिला है। Derived वर्ग में, मैं foo() सार्वजनिक लेकिन bar() निजी बनाना चाहता हूं। निम्न कोड ऐसा करने का सही और प्राकृतिक तरीका है?

class Base {
   public:
     void foo();
     void bar();
};

class Derived : public Base {
   private:
     void bar();
};

Answer #1

लिसकोव प्रतिस्थापन सिद्धांत के अनुसार, सार्वजनिक विरासत को मॉडल "ए-ए" होना चाहिए। आप सार्वजनिक रूप से Base से विरासत में Derived साथ जो कह रहे हैं, वह यह है कि जहां भी Base ऑब्जेक्ट की आवश्यकता होती है, वहां Derived प्रकार का ऑब्जेक्ट करेगा।

यदि आपको Base लिए उपलब्ध कुछ ऑपरेशंस को छिपाने के लिए डेरिव की आवश्यकता होती है, तो आप जो मॉडलिंग कर रहे हैं, वह "है-ए," के अलावा कुछ और है और सार्वजनिक विरासत सही उपकरण नहीं है।

आप जो चाहते हैं, वह या तो निजी उत्तराधिकार या रचना है, क्योंकि अन्य उत्तर विस्तृत हैं।


Answer #2

वास्तव में ऐसा कोई तरीका नहीं है जो आप चाहते हैं क्योंकि यदि आप Base से सार्वजनिक रूप से प्राप्त करते हैं, तो वर्ग का एक उपयोगकर्ता हमेशा सक्षम हो जाएगा:

Derived d;
Base& b = d;
b.bar();

आधार वर्ग से सार्वजनिक रूप से व्युत्पन्न वर्ग में सार्वजनिक आधार वर्ग के कार्यों को दुर्गम बनाने के लिए यह "सही या स्वाभाविक" नहीं है; इसके बजाय, बेस क्लास इंटरफ़ेस को ऐसे रीफ़्लैक्ट किया जाना चाहिए, जो उन कार्यों को सार्वजनिक नहीं कर रहे हैं या एक अलग वर्ग में विभाजित हैं।


Answer #3

C ++ 11 के साथ आप निम्नलिखित कार्य कर सकते हैं:

class Base {
   public:
     void foo();
     void bar();
};

class Derived : public Base {
   private:
     using Base::bar;  

};

यह सुनिश्चित करता है कि बेस :: बार () व्युत्पन्न वर्ग के बाहर से सुलभ नहीं है। यह बेस क्लास के बाहर से अभी भी सुलभ है।


Answer #4

मान लें कि आपके पास यह है:

class Foo{
public:
    void method1();
    void method2();
    void notGonnaSeeIt();
 private:
    //stuff
 };

इसे प्रभावी रूप से लपेटने के लिए आप या तो एक निजी विरासत कर सकते हैं और उन तरीकों को पारित कर सकते हैं जो आप सार्वजनिक घोषणा के लिए चाहते हैं जैसे कि ब्रायन ने सुझाव दिया है:

class Bar : private Foo{
    void methodA(){ method1(); }
    void methodB(){ method2(); }
    //more stuff
};

या आप इसे डेकोरेटर के साथ लपेट सकते हैं

template<class T>
class Bar{
public:
    Bar(T *_input) : m_Input(_input){}
    void methodA() { m_Input->method1(); }
    void methodB() { m_Input->method2(); }
    //whatever else you need/want
private:
    T* m_Input;
};

व्यक्तिगत रूप से, मैं टेम्पलेट तरीका पसंद करता हूं क्योंकि यह आपको किसी भी वर्ग के साथ वही काम करने की अनुमति देता है जो Foo से विरासत में मिला है।


Answer #5

सबसे पहले, आपको समझना होगा कि आप ओओपी के नजरिए से क्या करना चाहते हैं। विरासत के दो पूरी तरह से अलग-अलग प्रकार हैं:

  1. इंटरफ़ेस का विरासत। जब आप जावा या अन्य भाषाओं में implement करते हैं, जिनमें स्टैंडअलोन संस्थाओं के रूप में इंटरफेस होता है, तो यह तब भी होता है जब आप C ++ में खाली सार वर्ग से युवावस्था प्राप्त करते हैं। यहाँ आपको कोड के बारे में बिल्कुल भी परवाह नहीं है, लेकिन आप अपने संकलक और सभी को आधार / व्युत्पन्न वर्ग का उपयोग करके बताना चाहते हैं कि यह व्युत्पन्न वर्ग एक विशेष प्रकार का आधार वर्ग है, इसमें आधार वर्ग के सभी गुण हैं, यह बिल्कुल वैसा ही व्यवहार करता है बेस क्लास इसके उपयोगकर्ता द्वारा दिखाई देने वाली सीमा तक करता है, और इसका उपयोग बेस क्लास के बजाय किसी भी एल्गोरिदम में किया जा सकता है।

  2. संहिता का पालन। आपके पास बेस क्लास में कोड का एक टुकड़ा है जिसे आप अपने व्युत्पन्न वर्ग में फिर से उपयोग करना चाहते हैं। बेस क्लास और व्युत्पन्न वर्ग को किसी भी तरह से संबंधित होने की आवश्यकता नहीं है, आप बस कोड का पुन: उपयोग करना चाहते हैं और वह यह है।

C ++ में पब्लिक इनहेरिटेंस दोनों तरह का मिश्रण है, आपको इंटरफ़ेस इनहेरिटेंस मिलता है और आपको कोड इनहेरिटेंस भी मिलता है। निजी विरासत एक अलग तरह का जानवर है, आपको केवल कोड विरासत मिलता है, आपके व्युत्पन्न वर्ग के उपयोगकर्ता आधार वर्ग के बजाय इसका उपयोग नहीं कर सकते हैं और उपयोगकर्ता के दृष्टिकोण से आधार और व्युत्पन्न वर्गों का कोई संबंध नहीं है, इसलिए कभी भी।

struct Base {};
struct PublicDerived : public Base {};
struct PrivateDerived: private Base {};

Base * base; PublicDerived * public_derived; PrivateDerived * private_derived;

base = public_derived; //good
base = private_derived; //compilation error.

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


Answer #6

यदि आपको बाद में बेस क्लास के रूप में इसका इलाज करने की आवश्यकता नहीं है और केवल बेस क्लास के कुछ कार्यों की आवश्यकता है, तो आप विरासत के बजाय रचना का उपयोग कर सकते हैं? (C # मेरी पहली भाषा है, लेकिन आपको इसका विचार है)

class Base {
    public void foo();
    public void bar();
};

class Derived {
    private Base _base;

    public void bar() {
        _base.bar();
    }
};




c++