C++ 为什么受保护不保护此类中的成员?

C++ 为什么受保护不保护此类中的成员?,c++,C++,测试等级: class Base { protected: union { struct { bool bBold : 1; bool bFakeBold : 1; }; int a; }; public: bool isBold() { return bBold;

测试等级:

class Base {
    protected:
        union {
            struct {
                bool bBold : 1;
                bool bFakeBold : 1;
            };
            int a;
        };
    public:
        bool isBold() {
            return bBold;
        }
};
#包括
#包括
int main()
{
碱基d;
d、 bBold=假;
断言(d.isBold()==false);
d、 bBold=true;
断言(d.isBold()==true);
printf(“良好”);
返回0;
}
msvc11和g++编译时没有任何错误


为什么?

私有/受保护字段仅保护与关键字在同一类中定义的字段。如果有人会做以下的把戏:

#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;
}
您仍然可以访问
Foo::PublicBar::x

<>代码>结构x{}.}/COM>是C++中的一个SynOnm,它是代码>类X {public:…}//>。联盟的领域也是公开的

在您的情况下,可以通过以下方式隐藏它:

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

现在,
x
是私有的,内部接头的定义不会“泄露”到公众中。

按照标准,以下代码是不正确的

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

然而,当您尝试访问
bBold
时,clang会给出错误,因此,这可能是MSVC/GCC错误(我认为,这一切都取决于此扩展的实现,因为如果您尝试访问
a
成员,您将收到正确的错误)


因此,由于它是
C扩展
,我们没有访问说明符-看起来这个匿名结构的成员将被注入
公共
部分。

如前所述,未命名结构是一个非标准扩展。因为这是一个非标准的扩展,所以不同的编译器以细微的不同实现这一点是有效的。然而,对于匿名工会,同样的问题也存在。修改示例:

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

这应该会导致编译时错误/警告/其他诊断,但GCC很乐意接受它。按照4.5.3和Ideone的4.7.2进行测试。我怀疑这是GCC中的一个错误,如果MSVC也接受这一点,MSVC中也是一个错误。

看起来是不使用联合的另一个原因。clang 3.2给出了
错误:“bBold”是“Base”的受保护成员。
。gcc 4.7.2没有抱怨(对于
受保护的
,甚至对于
私有的
),msvc发出警告,gcc也发出警告,带有
-Wpedantic
。我不确定是否违反了标准。请注意,嵌套的
结构
不是
嵌套类型
,而是匿名结构类型的嵌套非静态对象。@CygnusX1匿名结构没有名称是标准不允许的,正如我所看到的,它是gnu扩展。那么这是违反标准的,但不是您引用的。这里没有嵌套类型定义,是吗?+1。对于那些对标准中没有名字的结构到底允许什么感到困惑的人(正如我在看到你的答案后困惑了片刻):我认为这个问题的答案没有那么“深刻”。这段代码没有同样的问题(特别是在
gcc
中):
class Base{protected:struct{bool bBold;bool bFakeBold;};…
class C {
    union {
        union {
            int i;
        };
    };
};
int main() {
    C c;
    c.i = 0;
    return c.i;
}