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

테스트 클래스 :protected가이 클래스의 멤버를 보호하지 않는 이유는 무엇입니까?

#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 모두와 g ++ 오류없이 컴파일합니다.

왜?

+0

노동 조합을 사용하지 않는 또 다른 이유가 있습니다. –

+0

clang 3.2'error : 'bBold'는 예상대로 'Base'의 보호 된 멤버입니다. gcc 4.7.2가 불평하지 않음 ('protected'및 'private'에 대해서도) – alfC

+0

msvc는 경고를 표시합니다. [C4201] (http://msdn.microsoft.com/en-us/library/c89bw853(v=vs) .71) .aspx) – spiritwolfform

답변

8

다음 코드는 표준에 맞지 않습니다.

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

그것은 아마 MSVC/GCC 버그 (모든이 확장의 실현에 따라, 당신은 bBold에 접근 할 때 GNU-extension

그러나, 그 소리는, 오류를 제공, 그래서, 나는 경우 때문에, 생각 a 회원에 액세스하려고 시도하면 올바른 오류가 표시됩니다.

따라서 액세스 지정자가없는 C-extension이므로이 익명 구조체의 멤버가 public 섹션에 삽입 된 것처럼 보입니다.

+1

표준에 위배되는지 확실하지 않습니다. 중첩 된'struct'는''중첩 된 타입''이 아니라 익명의 struct 타입의 중첩 된 비 정적 객체입니다. – CygnusX1

+0

이름이없는 @ CygnusX1 익명 구조체는 표준에서 허용되지 않습니다. gnu 확장자입니다. – ForEveR

+2

그러면 *는 * 표준에 위배됩니다. 그러나 여러분이 인용하는 것은 아닙니다. 여기에는 중첩 된 타입 정의가 없습니다. – CygnusX1

0

private/protected는 키워드와 동일한 클래스에 정의 된 필드 만 보호합니다. 하나는 다음과 같은 트릭을 할 것입니다 경우

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

을 당신은 여전히 ​​Foo::PublicBar::x

struct X { ... }class X { public: ... }의 synonim ++ C에서 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 '와) 같은 문제가 없습니다 : class Base { protected : struct { bool bBold; bool bFakeBold; }; ... ' – alfC

2

이미 언급했듯이 명명되지 않은 구조체는 비표준 확장자입니다. 이것은 비표준 확장이기 때문에, 다른 컴파일러가이를 미묘하게 다르게 구현하는 것은 유효합니다. 그러나 익명화 된 노조의 경우 동일한 질문이 존재합니다. 수정 된 예 :

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

컴파일 타임 오류/경고/기타 진단이 필요하지만 GCC는이를 기꺼이 받아들입니다. 4.5.3 및 Ideone의 4.7.2로 테스트되었습니다. 나는 이것이 GCC의 버그라고 생각한다. MSVC가 MSVC의 버그이기도하다면 이것을 받아 들인다.

관련 문제