2013-06-25 3 views
12
class Base { 
    protected: 
     union { 
      struct { 
       bool bBold : 1; 
       bool bFakeBold : 1; 
      }; 
      int a; 
     }; 
    public: 
     bool isBold() { 
      return bBold; 
     } 
}; 

टेस्ट वर्ग:संरक्षित क्यों इस वर्ग में सदस्य की रक्षा नहीं करता है?

#include <assert.h> 
#include <stdio.h> 

int main() 
{ 
    Base d; 
    d.bBold = false; 
    assert(d.isBold() == false); 
    d.bBold = true; 
    assert(d.isBold() == true); 
    printf("good"); 
    return 0; 
} 

दोनों msvc11 और जी ++ किसी भी त्रुटि के बिना संकलन।

क्यों?

+0

यूनियनों का उपयोग न करने का एक और कारण ऐसा लगता है। –

+0

क्लैंग 3.2 'त्रुटि देता है:' bBold 'अपेक्षित के रूप में' बेस 'के संरक्षित सदस्य हैं। जीसीसी 4.7.2 शिकायत नहीं करता है ('संरक्षित 'और यहां तक ​​कि' निजी' के लिए) – alfC

+0

एमएसवीसी एक चेतावनी देता है [सी 4201] (http://msdn.microsoft.com/en-us/library/c89bw853 (v = बनाम .71) .aspx) – spiritwolfform

उत्तर

8

निम्नलिखित कोड मानक द्वारा गलत है।

 struct { 
      bool bBold : 1; 
      bool bFakeBold : 1; 
     }; 

यह GNU-extension

हालांकि, बजना त्रुटि देता है, जब आप bBold के लिए उपयोग करने की कोशिश है, तो, यह शायद MSVC/जीसीसी बग (सभी इस विस्तार की प्राप्ति पर निर्भर करता है, मुझे लगता है कि अगर के बाद से, आप a सदस्य तक पहुंचने का प्रयास करते हैं - आपको सही त्रुटि मिल जाएगी)।

इसलिए, क्योंकि यह C-extension है, जहां हमारे पास कोई एक्सेस विनिर्देशक नहीं है - ऐसा लगता है कि इस अज्ञात संरचना के सदस्यों को public अनुभाग में इंजेक्शन दिया जाएगा।

+1

मुझे यकीन नहीं है कि यह मानक के खिलाफ है या नहीं। ध्यान दें कि नेस्टेड 'स्ट्रक्चर '' nested type'' नहीं है लेकिन अज्ञात संरचना प्रकार का घोंसला रहित गैर स्थैतिक वस्तु है। – CygnusX1

+0

@ साइग्नसएक्स 1 नाम के बिना अज्ञात structs मानक द्वारा अनुमति नहीं है, यह gnu-एक्सटेंशन है जैसा कि मैं देख सकता हूं। – ForEveR

+2

फिर * वह * मानक के खिलाफ है, लेकिन आप जो उद्धरण देते हैं वह नहीं। यहां कोई नेस्टेड टाइप परिभाषा नहीं है, है ना? – CygnusX1

0

निजी/संरक्षित केवल उसी वर्ग में परिभाषित फ़ील्ड को कीवर्ड के रूप में संरक्षित करता है। एक निम्नलिखित चाल करना चाहते हैं:

class Foo { 
    private: 
    class Bar { 
     public: 
     int x; 
    } 
    public: 
    typedef Bar PublicBar; 
} 

तुम अब भी उपयोग कर सकते हैं Foo::PublicBar::x

struct X { ... } C++ class X { public: ... } के synonim nowdays है। संघ के क्षेत्र भी सार्वजनिक हैं।

आपके मामले में, आप निम्नलिखित तरीके से इसे छुपा सकते हैं:

class Base { 
protected: 
    union X { 
     struct { 
      bool bBold : 1; 
      bool bFakeBold : 1; 
     }; 
     int a; 
    }; 
    X x; 
public: 
    bool isBold() { 
     return x.bBold; 
    } 
}; 

अब x निजी है और भीतरी संघ की परिभाषा सार्वजनिक में "रिसाव" नहीं करता है।

+0

मुझे नहीं लगता कि सवाल का जवाब यह है कि "गहरा"। इस कोड में एक ही समस्या नहीं है (विशेष रूप से 'gcc' के साथ): 'कक्षा बेस { संरक्षित: संरचना { बूल बीबल्ड; बूल बीएफकेबल्ड; }; ... ' – alfC

2

जैसा कि पहले से ही उल्लेख किया गया है, अनामित structs एक गैर-मानक एक्सटेंशन है। चूंकि यह एक गैर-मानक विस्तार है, इसलिए यह अलग-अलग कंप्यूटर्स के लिए अलग-अलग लागू करने के लिए मान्य है। हालांकि, अज्ञात संघों के लिए, वही प्रश्न मौजूद है। संशोधित उदाहरण:

class C { 
    union { 
     union { 
      int i; 
     }; 
    }; 
}; 
int main() { 
    C c; 
    c.i = 0; 
    return c.i; 
} 

यह एक संकलन समय त्रुटि/चेतावनी/अन्य नैदानिक ​​कारण चाहिए, लेकिन जीसीसी खुशी से स्वीकार करता है। 4.5.3, और आइडिया के 4.7.2 के साथ परीक्षण किया गया। मुझे संदेह है कि यह जीसीसी में एक बग है, और यदि एमएसवीसी भी इसे स्वीकार करता है, तो एमएसवीसी में भी एक बग।

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

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