क्या आंतरिक कक्षाएं निजी चर तक पहुंच सकती हैं?


117
class Outer {

    class Inner {
    public:
        Inner() {}
        void func() ;
    };

private:
    static const char* const MYCONST;
    int var;
};

void Outer::Inner::func() {
    var = 1;
}

const char* const Outer::MYCONST = "myconst";

यह त्रुटि तब होती है जब मैं कक्षा बाहरी के साथ संकलित करता हूं :: इनर 'का कोई सदस्य नहीं है जिसका नाम `वेर' है।

जवाबों:


120

एक आंतरिक वर्ग उस वर्ग का मित्र होता है जिसे उसके भीतर परिभाषित किया जाता है।
तो हाँ; प्रकार का एक ऑब्जेक्ट प्रकार के ऑब्जेक्ट के Outer::Innerसदस्य चर तक पहुंच सकता है ।varOuter

जावा के विपरीत, हालांकि, प्रकार की Outer::Innerवस्तु और मूल वर्ग की वस्तु के बीच कोई संबंध नहीं है । आपको पैरेंट चाइल्ड रिलेशनशिप को मैनुअली बनाना होगा।

#include <string>
#include <iostream>

class Outer
{
    class Inner
    {
        public:
            Inner(Outer& x): parent(x) {}
            void func()
            {
                std::string a = "myconst1";
                std::cout << parent.var << std::endl;

                if (a == MYCONST)
                {   std::cout << "string same" << std::endl;
                }
                else
                {   std::cout << "string not same" << std::endl;
                }
            }
        private:
            Outer&  parent;
    };

    public:
        Outer()
            :i(*this)
            ,var(4)
        {}
        Outer(Outer& other)
            :i(other)
            ,var(22)
        {}
        void func()
        {
            i.func();
        }
    private:
        static const char* const MYCONST;
        Inner i;
        int var;
};

const char* const Outer::MYCONST = "myconst";

int main()
{

    Outer           o1;
    Outer           o2(o1);
    o1.func();
    o2.func();
}

14
तकनीकी रूप से वर्तमान सी ++ मानक में, एक नेस्टेड वर्ग को अपने संलग्न वर्ग के लिए विशेष पहुंच नहीं है। मानक के 11.8.1 सेकंड देखें। इस मानक दोष को भी देखें: open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45
ग्रेग रोजर्स

1
इसकी कीमत क्या है, इसके लिए जीसीसी प्रस्तावित प्रस्ताव का पालन करता है, अन्य कंपाइलर भी शायद करते हैं।
ग्रेग रोजर्स

24
C + 11 मानक अब उपरोक्त विवरण के अनुरूप है।
मार्टिन यॉर्क

1
जावा में, गैर-स्थैतिक आंतरिक वर्ग को स्पष्ट रूप से एक संदर्भ (पॉइंटर) दिया जाता है जब बाहरी कक्षा पहली बार एक्सेस की जाती है। इसे rephrase करने के लिए, jvm आपके लिए एक कोड लिख रहा है, जो @LokiAstari ने हमें उसके जवाब में दिखाया है। यहां प्रभावी जावा 2 एड "आइटम 22: गैर-स्थैतिक से अधिक स्थिर सदस्य वर्गों का एक अंश दिया गया है ": "यदि आप इस संशोधक को छोड़ देते हैं (आंतरिक वर्ग की घोषणा करते समय स्थिर कीवर्ड), तो प्रत्येक उदाहरण में इसके संलग्न उदाहरण का एक विलक्षण संदर्भ होगा"।
डेविड ली

3
@ लोकी एस्टरी: मैंने आखिरी वाक्य "आपको मूल बच्चे के संबंध को स्वयं बनाना है" पढ़ा और कोड के टुकड़े की व्याख्या की, जो इस बात का उदाहरण है कि कैसे सही तरीके से किया जाए !
ब्रेंट बेकाला

32

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


7
यह c ++ 11
thrantir

6

कुछ भी जो आउटर का हिस्सा है , आउटर के सभी सदस्यों, सार्वजनिक या निजी तक पहुंच होनी चाहिए।

संपादित करें: आपका कंपाइलर सही है, var इनर का सदस्य नहीं है। लेकिन अगर आपके पास बाहरी के उदाहरण के लिए एक संदर्भ या सूचक है, तो यह उस तक पहुंच सकता है।


2

var आंतरिक वर्ग का सदस्य नहीं है।

Var का उपयोग करने के लिए, एक पॉइंटर या बाहरी वर्ग के उदाहरण के संदर्भ का उपयोग किया जाना चाहिए। जैसे pOuter-> var काम करेगा अगर आंतरिक वर्ग बाहरी का दोस्त है, या, var सार्वजनिक है, अगर कोई C ++ मानक का सख्ती से पालन करता है।

कुछ संकलक आंतरिक कक्षाओं को बाहरी के मित्र के रूप में मानते हैं, लेकिन कुछ नहीं कर सकते। IBM कंपाइलर के लिए यह दस्तावेज़ देखें :

"एक नेस्टेड क्लास को दूसरे क्लास के दायरे में घोषित किया जाता है। नेस्टेड क्लास का नाम उसके एनक्लोजिंग क्लास के लिए स्थानीय होता है। जब तक आप स्पष्ट पॉइंटर्स, रेफरेंस या ऑब्जेक्ट नेम का इस्तेमाल नहीं करते हैं, तब तक नेस्टेड क्लास में डिक्लेयर कंस्ट्रक्शंस का इस्तेमाल कर सकते हैं। नाम, स्थिर सदस्य और संलग्नक वर्ग और वैश्विक चर से प्रगणक टाइप करें।

नेस्टेड क्लास के सदस्य कार्य नियमित पहुँच नियमों का पालन करते हैं और उनके संलग्न वर्गों के सदस्यों के लिए कोई विशेष पहुँच विशेषाधिकार नहीं है। संलग्न वर्ग के सदस्य कार्यों में एक नेस्टेड वर्ग के सदस्यों के लिए कोई विशेष पहुंच नहीं है। "


4
गलत। अन्य उत्तर देखें - 3 साल पहले। "अगर कोई C ++ मानक का कड़ाई से पालन करता है", तो वे आपसे अलग-अलग जवाबों तक पहुंचते हैं। C ++ 11 के शुरुआती मसौदे के अनुसार, नेस्टेड क्लास एक संदर्भ / सूचक के माध्यम से माता-पिता के सभी सदस्यों तक पहुंच सकते हैं । स्पष्ट रूप से घोषित करने friendया करने की कोई आवश्यकता नहीं है public। अगर मृत अवस्था में आईबीएम गलत / आउटडेटेड हो जाता है, तो कौन परवाह करता है? यह उत्तर पोस्ट किए जाने से 3 साल पहले से ही पुराना था।
अंडरस्कोर_ड

1

सबसे पहले, आप varवर्ग के बाहर गैर-स्थैतिक सदस्य तक पहुंचने का प्रयास कर रहे हैं, जिसे C ++ में अनुमति नहीं है।

मार्क का जवाब सही है।

कुछ भी जो आउटर का हिस्सा है, आउटर के सभी सदस्यों, सार्वजनिक या निजी तक पहुंच होनी चाहिए।

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

स्थैतिक संस्करण

बदलें varकरने के लिए staticयदि आप नहीं चाहते हैं varवर्ग के उदाहरण के साथ जुड़े होने।

#include <iostream>

class Outer {

private:
    static const char* const MYCONST;
    static int var;

public:
   class Inner {
    public:
        Inner() {
          Outer::var = 1;
        }
        void func() ;
    };
};

int Outer::var = 0;

void Outer::Inner::func() {
    std::cout << "var: "<< Outer::var;
}

int main() {
  Outer outer;
  Outer::Inner inner;
  inner.func();

}

आउटपुट- var: 1

गैर-स्थिर संस्करण

किसी ऑब्जेक्ट का संदर्भ किसी भी गैर-स्थैतिक सदस्य चर तक पहुँच होना चाहिए।

#include <iostream>

class Outer {

private:
    static const char* const MYCONST;
    int var;

public:
   class Inner {
    public:
        Inner(Outer &outer) {
          outer.var = 1;
        }
        void func(const Outer &outer) ;
    };
};

void Outer::Inner::func(const Outer &outer) {
    std::cout << "var: "<< outer.var;
}

int main() {
  Outer outer;
  Outer::Inner inner(outer);
  inner.func(outer);

}

आउटपुट- var: 1

संपादित करें - बाहरी लिंक मेरे ब्लॉग के लिंक हैं।

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