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;
}