निजी और संरक्षित सदस्य: C ++


276

क्या कोई मुझे कक्षाओं में privateऔर protectedसदस्यों के बीच के अंतर के रूप में बता सकता है ?

मैं सर्वश्रेष्ठ अभ्यास सम्मेलनों से समझता हूं कि चर और फ़ंक्शन जिन्हें कक्षा के बाहर नहीं बुलाया जाता है, उन्हें बनाया जाना चाहिए private- लेकिन मेरे एमएफसी प्रोजेक्ट को देखते हुए, एमएफसी के पक्ष में लगता है protected

क्या अंतर है और मुझे किसका उपयोग करना चाहिए?

जवाबों:


374

निजी सदस्य केवल उन्हें परिभाषित करने वाले वर्ग के भीतर ही पहुंच सकते हैं।

संरक्षित सदस्य उस वर्ग में सुलभ होते हैं जो उन्हें परिभाषित करता है और उन कक्षाओं में जो उस वर्ग से विरासत में मिलते हैं।

संपादित करें: दोनों भी अपने वर्ग के दोस्तों द्वारा और उनकी व्युत्पन्न कक्षाओं के दोस्तों द्वारा संरक्षित हैं।

संपादित करें 2: अपनी समस्या के संदर्भ में जो कुछ भी समझ में आता है उसका उपयोग करें। जब भी आप युग्मन को कम करने और आधार वर्ग के कार्यान्वयन की रक्षा कर सकते हैं, तब आपको सदस्यों को निजी बनाने का प्रयास करना चाहिए, लेकिन यदि यह संभव नहीं है, तो संरक्षित सदस्यों का उपयोग करें। समस्या की बेहतर समझ के लिए C ++ FAQ देखें । संरक्षित चर के बारे में यह प्रश्न भी मदद कर सकता है।


12
सी ++ एफएक्यू लाइट का लिंक isocpp.org/wiki/faq/basics-of-inheritance
av

134

एक वर्ग ए के सार्वजनिक सदस्य सभी और सभी के लिए सुलभ हैं।

वर्ग A के संरक्षित सदस्य A के कोड के बाहर पहुंच योग्य नहीं हैं, लेकिन A से प्राप्त किसी भी वर्ग के कोड से पहुंच योग्य हैं।

A के वर्ग के निजी सदस्य A के कोड के बाहर या A से प्राप्त किसी भी वर्ग के कोड से सुलभ नहीं हैं।

तो, अंत में, संरक्षित या निजी के बीच चयन करना निम्नलिखित प्रश्नों का उत्तर दे रहा है: आप व्युत्पन्न वर्ग के प्रोग्रामर में कितना विश्वास करने के लिए तैयार हैं?

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


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

@CashCow the protected data of the base class is part of the data of the derived class.वास्तव में। क्या यह बेहतर नहीं है, फिर, व्युत्पन्न वर्ग के लेखक ने उस डेटा को अपनी कक्षा में घोषित किया, मेरे बजाय ...? ... :-) ... The writer of the derived class is expected to handle this data properly or it is a bug.एनवीआई पैटर्न में, उद्देश्य सब कुछ निजी बनाना है, जिसमें शामिल है तरीकों, क्षति को सीमित करने के लिए व्युत्पन्न वर्ग लेखक पदानुक्रम के लिए कर सकता है। संरक्षित तरीके पहले से ही एक संभावित समस्या है। मैं इस बात से सहमत नहीं हूं कि संरक्षित राज्य का उपयोग करके यह सही दृष्टिकोण है।
पियरसबल

यह हो सकता है, जिससे आपको इसे एक्सेस करने के लिए बेस क्लास में वर्चुअल "गेटर्स" की आवश्यकता होगी। और जब तक आप डेटा पैटर्न को लागू करने के विभिन्न तरीकों को करने के लिए इन-बीच कक्षाएं कर सकते हैं, ऐसा करना हमेशा व्यावहारिक नहीं होता है। उदाहरण के लिए, भाषाओं में एक "पैटर्न", जो कि सामान्य रूप से "कास्ट" संशोधक नहीं है, C ++ में अधिकांश समय आवश्यक नहीं है, केवल पढ़ने के लिए आधार वर्ग और लेखन योग्य व्युत्पन्न वर्ग हैं। C ++ में यह केवल इसलिए भी अच्छा हो सकता है क्योंकि आप डेटा को लोड करने (आरंभ करने) में एक से अधिक संभव तरीके चाहते हैं।
कैशबैक

ऐसा करने के लिए विभिन्न तरीके हैं। अपने क्रमांकन वर्गों को मित्र बनाएं। अपने सभी डेटा को सार्वजनिक पहुंच के साथ एक संरचना में डालें लेकिन आपकी कक्षा में इस चर का एक निजी सदस्य है .... संरक्षित सदस्य और व्युत्पन्न वर्ग इसे जो भी स्रोत कभी-कभी आसान होता है उसे लोड करने के लिए।
कैशबैक

63

संरक्षित सदस्यों को व्युत्पन्न वर्गों से पहुँचा जा सकता है। निजी वाले नहीं कर सकते।

class Base {

private: 
  int MyPrivateInt;
protected: 
  int MyProtectedInt;
public:
  int MyPublicInt;
};

class Derived : Base
{
public:
  int foo1()  { return MyPrivateInt;} // Won't compile!
  int foo2()  { return MyProtectedInt;} // OK  
  int foo3()  { return MyPublicInt;} // OK
};‌‌

class Unrelated 
{
private:
  Base B;
public:
  int foo1()  { return B.MyPrivateInt;} // Won't compile!
  int foo2()  { return B.MyProtectedInt;} // Won't compile
  int foo3()  { return B.MyPublicInt;} // OK
};

"सर्वोत्तम अभ्यास" के संदर्भ में, यह निर्भर करता है। अगर ऐसी कोई बेहूदा संभावना है कि कोई आपके मौजूदा व्यक्ति से एक नया वर्ग प्राप्त करना चाहता है और आंतरिक सदस्यों तक पहुंच की आवश्यकता है, तो उन्हें संरक्षित करें, निजी नहीं। यदि वे निजी हैं, तो आपकी कक्षा को आसानी से विरासत में प्राप्त करना मुश्किल हो सकता है।


3
मैं अलग होने की भीख माँगता हूँ: अगर कोई बेहूदा संभावना है कि किसी उपवर्ग को इसकी आवश्यकता नहीं है, तो इसे निजी बनाएं। जब तक आप अपने वर्ग को उपवर्गित करने का इरादा नहीं करते, तब तक टेम्पलेट विधि पैटर्न का उपयोग करें।
xtofl

23

MFC के पक्ष में संरक्षित होने का कारण यह है कि यह एक ढांचा है। आप संभवतः MFC वर्गों को उप-वर्ग करना चाहते हैं और उस स्थिति में उन तरीकों तक पहुँचने के लिए एक संरक्षित इंटरफ़ेस की आवश्यकता होती है जो कक्षा के सामान्य उपयोग के लिए दृश्यमान नहीं हैं।


9

यह सब इस बात पर निर्भर करता है कि आप क्या करना चाहते हैं, और आप क्या चाहते हैं कि व्युत्पन्न वर्ग देख सकें।

class A
{
private:
    int _privInt = 0;
    int privFunc(){return 0;}
    virtual int privVirtFunc(){return 0;}
protected:
    int _protInt = 0;
    int protFunc(){return 0;}
public:
    int _publInt = 0;
    int publFunc()
    {
         return privVirtFunc();
    }
};

class B : public A
{
private:
    virtual int privVirtFunc(){return 1;}
public:
    void func()
    {
        _privInt = 1; // wont work
        _protInt = 1; // will work
        _publInt = 1; // will work
        privFunc(); // wont work
        privVirtFunc(); // wont work
        protFunc(); // will work
        publFunc(); // will return 1 since it's overridden in this class
    }
}

6

विशेषताएँ और तरीके के रूप में चिह्नित protected हैं - निजी लोगों के विपरीत - अभी भी उपवर्गों में दिखाई देते हैं।

जब तक आप संभावित उपवर्गों में विधि को ओवरराइड करने की संभावना का उपयोग या प्रदान नहीं करना चाहते हैं, मैं उन्हें बनाऊंगा private


2
एक व्युत्पन्न वर्ग अपने आधार के निजी आभासी कार्यों को ओवरराइड कर सकता है
जेम्स हॉपकिन

6

निश्चित रूप से संरक्षित सदस्य चर के प्रश्न पर एक नज़र डालें । यह classयुग्मन को कम करने के लिए एक डिफ़ॉल्ट के रूप में निजी का उपयोग करने के लिए अनुशंसित है (जैसे सी ++ सीस करते हैं)। संरक्षित सदस्य चर सबसे खराब विचार हैं, संरक्षित सदस्य कार्यों का उपयोग टेम्पलेट विधि पैटर्न के लिए किया जा सकता है।


इससे पहले कि मैंने तुम्हारा देखा, मजेदार, मैंने उसे अपनी पोस्ट में संपादित किया। अपवित्र क्योंकि एक ही लिंक पर एक पंख के पक्षी ठोकर खाते हैं :)
फ़िरस असद

4

संरक्षित सदस्यों को केवल कक्षा के वंशजों और उसी मॉड्यूल में कोड द्वारा पहुँचा जा सकता है। निजी सदस्यों को केवल उस वर्ग द्वारा एक्सेस किया जा सकता है जिसे उन्होंने घोषित किया है और उसी मॉड्यूल में कोड द्वारा।

बेशक दोस्त के कामों ने इसे खिड़की से बाहर फेंक दिया, लेकिन ओह ठीक है।


4

निजी सदस्य केवल कक्षा के भीतर से ही पहुँच योग्य हैं, संरक्षित सदस्य वर्ग और व्युत्पन्न वर्गों में पहुँच योग्य हैं। यह OO भाषाओं में वंशानुक्रम की एक विशेषता है।

आपके पास C ++ में निजी, संरक्षित और सार्वजनिक विरासत हो सकती है, जो यह निर्धारित करेगी कि वंशानुगत पदानुक्रम में कौन से व्युत्पन्न वर्ग एक्सेस कर सकते हैं। उदाहरण के लिए C # में केवल सार्वजनिक विरासत है।


3

निजी (केवल माता-पिता (आधार वर्ग) द्वारा सुलभ (अर्थात केवल मेरे माता-पिता ही मेरे माता-पिता के बेडरूम में जा सकते हैं)

संरक्षित (मातृत्व (आधार वर्ग), और उसकी बेटियों द्वारा सुलभ (यानी केवल मेरे माता-पिता ही मेरे माता-पिता के बेडरूम में जा सकते हैं, लेकिन बेटे / बेटी को माता-पिता के बेडरूम में चलने की अनुमति दी है)

सार्वजनिक = मातृत्व (आधार वर्ग), बेटी, और अन्य सभी के द्वारा सुलभ (अर्थात केवल मेरे माता-पिता ही मेरे माता-पिता के बेडरूम में जा सकते हैं, लेकिन यह एक घर की पार्टी है - mi casa su casa)


2

चूंकि व्युत्पन्न वर्ग में संरक्षित सदस्यों को लाने और अद्यतन करने के लिए किसी सार्वजनिक सदस्य फ़ंक्शन की आवश्यकता नहीं होती है, इससे कोड की दक्षता बढ़ जाती है और हमें लिखने के लिए आवश्यक कोड की मात्रा कम हो जाती है। हालाँकि, व्युत्पन्न वर्ग के प्रोग्रामर को यह पता होना चाहिए कि वह क्या कर रहा है।


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

2

privateसदस्य डेटा के लिए पसंद किया जाता है। C ++ कक्षाओं में सदस्य हैंprivate डिफ़ॉल्ट रूप से हैं।

publicसदस्य कार्यों के लिए पसंद किया जाता है, हालांकि यह राय का विषय है। कम से कम कुछ तरीके सुलभ होने चाहिए। publicसभी के लिए सुलभ है। यह सबसे लचीला विकल्प है और कम से कम सुरक्षित है। कोई भी उनका उपयोग कर सकता है, और कोई भी उनका दुरुपयोग कर सकता है।

privateसुलभ नहीं है। वर्ग के बाहर कोई भी उनका उपयोग नहीं कर सकता है, और कोई भी उनका दुरुपयोग नहीं कर सकता है। व्युत्पन्न वर्गों में भी नहीं।

protectedएक समझौता है क्योंकि इसका उपयोग व्युत्पन्न वर्गों में किया जा सकता है। जब आप एक वर्ग से निकलते हैं, तो आपको आधार वर्ग की अच्छी समझ होती है, और आप सावधान रहते हैं कि इन सदस्यों का दुरुपयोग न करें।

MFC Windows API के लिए C ++ आवरण है, यह पसंद करता है publicऔर protected। विजुअल स्टूडियो द्वारा उत्पन्न कक्षा जादूगर की एक बदसूरत मिश्रण protected, publicऔरprivate सदस्य हैं। लेकिन खुद MFC वर्गों के लिए कुछ तर्क है।

सदस्य जैसे SetWindowTextहैं, publicक्योंकि आपको अक्सर इन सदस्यों तक पहुंचने की आवश्यकता होती है।

सदस्य जैसे OnLButtonDown, खिड़की द्वारा प्राप्त सूचनाओं को संभालते हैं। उन्हें एक्सेस नहीं किया जाना चाहिए, इसलिए वे हैं protected। आप इन फ़ंक्शंस को ओवरराइड करने के लिए अभी भी उन्हें व्युत्पन्न वर्ग में एक्सेस कर सकते हैं।

कुछ सदस्यों को थ्रेड्स और संदेश लूप्स करने होते हैं, उन्हें एक्सेस या ओवरराइड नहीं किया जाना चाहिए, इसलिए उन्हें घोषित किया जाता है private

C ++ संरचनाओं में, सदस्य publicडिफ़ॉल्ट रूप से होते हैं। संरचनाएं आमतौर पर केवल डेटा के लिए उपयोग की जाती हैं, विधियों के लिए नहीं, इसलिए publicघोषणा को सुरक्षित माना जाता है।


1
आप लिखते हैं "C ++ कक्षाओं में सदस्य डिफ़ॉल्ट रूप से सुरक्षित हैं"। मानक के अनुसार, वे डिफ़ॉल्ट रूप से या तो निजी या सार्वजनिक हैं, जिसके आधार पर परिभाषा (14p3) में कीवर्ड का उपयोग किया गया था। क्या Microsoft यहाँ मानक से विचलन करता है?
अलेक्जेंडर क्लाउर

@AlexanderKlauer मैं गलत था, यह privateदृश्य स्टूडियो में डिफ़ॉल्ट रूप से है। यह privateडिफ़ॉल्ट रूप से gcc में भी है, यह publicडिफ़ॉल्ट रूप से कभी नहीं है। जब तक मैं फिर से गलत नहीं हूँ। मैं उस मानक को नहीं ढूँढ सकता जिसका आप उल्लेख कर रहे हैं।
बरमक शेमिरानी

क्षमा करें, मुझे और अधिक स्पष्ट होना चाहिए था। मैं C ++ 17 मानक का जिक्र कर रहा था। C ++ 11 मानक में 11p3 में एक ही शब्दांकन है। क्या आप अपना उत्तर अपडेट कर सकते हैं? धन्यवाद!
बजे अलेक्जेंडर क्लाउर

1

निजी सदस्य को केवल उसी कक्षा में पहुँचा जा सकता है जहाँ उसने यह घोषित किया है कि जहाँ संरक्षित सदस्य को कक्षा में पहुँचा जा सकता है जहाँ उसे उन वर्गों के साथ घोषित किया जाता है जो उसके द्वारा विरासत में प्राप्त किए जाते हैं।


1
  • निजी : यह एक एक्सेस स्पेसियर है। डिफ़ॉल्ट रूप से उदाहरण (सदस्य) चर या c ++ / java में एक वर्ग के तरीके निजी हैं। वंशानुक्रम के दौरान, कोड और डेटा हमेशा विरासत में मिलते हैं, लेकिन कक्षा के बाहर पहुंच योग्य नहीं होते हैं। हम अपने डेटा सदस्यों को निजी घोषित कर सकते हैं ताकि कोई भी हमारे सदस्य चर में प्रत्यक्ष परिवर्तन न कर सके और हम अपने निजी सदस्यों को बदलने के लिए सार्वजनिक गेटवे और सेटर प्रदान कर सकें। और इस अवधारणा को हमेशा व्यापार नियम में लागू किया जाता है।

  • संरक्षित : यह एक एक्सेस स्पेसियर भी है। C ++ में, संरक्षित सदस्य वर्ग के भीतर और विरासत में प्राप्त वर्ग तक पहुँच योग्य हैं, लेकिन कक्षा के बाहर नहीं। जावा में, संरक्षित सदस्य वर्ग के भीतर, विरासत में मिली कक्षा के साथ-साथ एक ही पैकेज के भीतर सभी वर्गों के लिए सुलभ हैं।


0

एक संरक्षित नॉनस्टैटिक बेस क्लास सदस्य को निम्न बेस में से किसी एक का उपयोग करके उस बेस क्लास से प्राप्त किसी भी वर्ग के सदस्यों और दोस्तों द्वारा एक्सेस किया जा सकता है:

  • प्रत्यक्ष या अप्रत्यक्ष रूप से व्युत्पन्न वर्ग के लिए एक सूचक
  • प्रत्यक्ष या परोक्ष रूप से व्युत्पन्न वर्ग का संदर्भ
  • प्रत्यक्ष या परोक्ष रूप से व्युत्पन्न वर्ग की वस्तु

0

निजी: कक्षा के सदस्य कार्यों और मित्र समारोह या मित्र वर्ग द्वारा सुलभ। C ++ क्लास के लिए यह डिफॉल्ट एक्सेस स्पेसियर है।

संरक्षित: वर्ग के सदस्य कार्यों, मित्र समारोह या मित्र वर्ग और व्युत्पन्न वर्गों द्वारा सुलभ।

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

अधिक विस्तार के लिए इस लिंक को देखें


-2

निजी और संरक्षित एक्सेस मोडिफायर एक और एक ही है कि बेस क्लास के संरक्षित सदस्यों को बच्चे (व्युत्पन्न) क्लास में बेस क्लास के दायरे से बाहर पहुँचा जा सकता है। यह विरासत में भी वही लागू होता है। लेकिन निजी संशोधक के साथ बेस क्लास के सदस्यों को केवल बेस क्लास के दायरे या कोड में पहुँचा जा सकता है और उसका मित्र केवल '' '' पर काम करता है।


5
आपका जवाब अन्य उत्तरों पर क्या मूल्य जोड़ता है?
हरमन डॉप्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.