2010-08-21 30 views
16

इस कोड पर संकलित से enclosing वर्ग की रक्षा की सदस्य तक पहुंच MSVC/जी ++:नेस्टेड कक्षाएं: एक नेस्टेड संरक्षित वर्ग

class A{ 
protected: 
    int i; 
    class B{ 
    public: 
     A* a; 
     B(A* a_) 
     :a(a_){ 
     } 
     void doSomething(){ 
      if (a) 
       a->i = 0;//<---- this part 
     }  
    }; 
public: 
    A() 
    :i(0){ 
    } 
}; 

आप देख सकते हैं, बी वर्ग enclosing के "सुरक्षित" खंड के लिए उपयोग हो जाता है, हालांकि इसे मित्र के रूप में घोषित नहीं किया गया है।

क्या यह एक मानक (मानक-अनुरूप) व्यवहार है?

मैं कभी-कभी इस सुविधा का उपयोग करता हूं, लेकिन मुझे यह नियम याद नहीं है कि नेस्टेड संरक्षित वर्ग को स्वचालित रूप से संलग्न वर्ग के सभी संरक्षित डेटा तक पहुंच प्राप्त करनी चाहिए।

+0

डुपे प्रश्न। मैं अब मूल की खोज नहीं कर रहा हूं, हालांकि। :) –

उत्तर

13

सी ++ 03 मानक में, 11.8p1 का कहना है:

एक नेस्टेड वर्ग के सदस्य एक संलग्नित क्लास के सदस्यों के लिए कोई विशेष उपयोग कर सकते है।

हालांकि, defect report 45 के लिए संकल्प (मानक करने के लिए) के सामने कहा गया है, और इसलिए व्यवहार को परिभाषित करता आप देखते हैं:

एक नेस्टेड वर्ग एक सदस्य है और जैसे ही पहुँच गया है किसी अन्य सदस्य के रूप में अधिकार।

C++ 0x ने 11.8 का मूल पाठ इस तथ्य को प्रतिबिंबित करने के लिए बदल दिया गया है, तो यह दोनों सी ++ 03 और C++ 0x अनुरूप compilers के लिए मान्य व्यवहार है।

cprogramming.com फ़ोरम से this thread भी देखें।

+2

+1 अच्छा जवाब। हालांकि, अगर आप इसे Google करते हैं, तो कुछ आईबीएम एक्सएल कंपाइलर दस्तावेज हैं जो केवल आपके द्वारा बताए गए पहले भाग का उल्लेख करते हैं और इसका तात्पर्य है कि ओपी का कोड संकलित नहीं होगा। तो पोर्टेबल चीज वर्तमान में करने के लिए, जब तक सी ++ 0x व्यापक रूप से कार्यान्वित नहीं किया जाता है, तो घोंसला वर्ग को संलग्न वर्ग के भीतर मित्र के रूप में घोषित करना होगा। – Praetorian

+0

अच्छा खोज। पूर्णता के लिए एक लिंक अच्छा होगा। :) –

+0

मैं पहले आलसी था :-), यह लिंक है। http://publib.boulder.ibm.com/infocenter/comphelp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.aix.doc/language_ref/cplr061.html – Praetorian

0

$ 9.7/1 का संदर्भ लें।

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

5

मैं की सी ++ 03 काम एक प्रति नहीं है, लेकिन एक मसौदा (n3090) C++ 0x की से:

11,8 नेस्टेड कक्षाएं

एक नेस्टेड कक्षा एक सदस्य है और इस तरह के किसी भी अन्य सदस्य के रूप में पहुंच अधिकार है। एक संलग्न कक्षा के सदस्यों के पास नेस्टेड कक्षा के सदस्यों के लिए विशेष पहुंच नहीं है; सामान्य पहुंच नियम (खंड 11) का पालन किया जाएगा।

[उदाहरण:

class E { 
    int x; 
    class B { }; 
    class I { 
     B b; // OK: E::I can access E::B 
     int y; 
     void f(E* p, int i) { 
      p->x = i; // OK: E::I can access E::x 
     } 
    }; 
    int g(I* p) { 
     return p->y; // error: I::y is private 
    } 
}; 

तो कम से कम अगले मानक में, संलग्न कक्षाएं किसी भी सामान्य सदस्य होगा समारोह के रूप में बाहरी वर्ग 'के सदस्यों को एक्सेस कर सकते हैं।

अद्यतन: वर्तमान मानक में इसकी अनुमति नहीं है। लेकिन एक दोष रिपोर्ट (DR 45) इसे ठीक करने के लिए दायर की गई थी।(SigTerm के संपादन बाहर इस एक ले लिया कृपया, सावधान रहें।।)

अद्यतन # 2: मैं -Wall -ansi -pedantic -std=c++98 और साथ VS2010, जी ++ (4.0.1 एप्पल) के साथ की कोशिश की Comeau (4.3.10.1) में सख्त सी + +03 मोड सी ++ 0x एक्सटेंशन अक्षम के साथ - वे सभी आंतरिक वर्ग के सदस्यों में बाहरी वर्ग private सदस्यों तक पहुंच स्वीकार करते हैं।

0

क्या यह एक मानक (मानक-अनुरूप) व्यवहार है?

नहीं। 2003

Section 11.8.1

नेस्टेड कक्षाएं

एक नेस्टेड वर्ग के सदस्य एक संलग्नित क्लास के सदस्यों के लिए कोई विशेष उपयोग किया है, और न ही वर्ग या कार्यों के लिए -

C++ के अनुसार

जिसने एक संलग्न वर्ग को दोस्ती दी है; सामान्य पहुंच नियम (धारा 11) का पालन किया जाएगा। एक संलग्न वर्ग के सदस्यों के पास घोंसला वाले वर्ग के सदस्यों के लिए कोई विशेष पहुंच नहीं है; सामान्य पहुंच नियम (धारा 11) का पालन किया जाएगा।

[Example: 
class E { 

    int x; 
    class B { }; 
    class I { 

     B b; //error: E::B is private 
     int y; 
     void f(E* p, int i) 
     { 
      p->x = i;   //error: E::x is private 
     } 
    }; 
    int g(I* p) 
    { 
      return p->y; //error: I::y is private 
    } 
}; 
—end example] 

लेकिन वहाँ ISO/IEC N 3092 में उस अनुभाग के लिए एक मामूली संशोधन जो कहते हैं

एक नेस्टेड वर्ग एक सदस्य है और इस तरह के किसी अन्य सदस्य के रूप में ही अधिकारों का उपयोग किया है। एक संलग्न वर्ग के सदस्यों के पास घोंसला वाले वर्ग के सदस्यों के लिए कोई विशेष पहुंच नहीं है; सामान्य पहुंच नियम (धारा 11) का पालन किया जाएगा।

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