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和g ++都编译没有任何错误。
为什么?
答案 0 :(得分:8)
以下代码标准不正确。
struct {
bool bBold : 1;
bool bFakeBold : 1;
};
然而,当你试图访问bBold
时,clang会出错,因此,它可能是MSVC / GCC错误(我认为,所有这些都取决于此扩展的实现,因为如果你试图访问{ {1}}成员 - 您将收到正确的错误。)
所以,因为它是a
,我们没有访问说明符 - 看起来这个匿名结构的成员将被注入C-extension
部分。
答案 1 :(得分: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中的一个错误。
答案 2 :(得分:0)
private / protected仅保护与关键字在同一类中定义的字段。如果有人会做以下诀窍:
class Foo {
private:
class Bar {
public:
int x;
}
public:
typedef Bar PublicBar;
}
您仍然可以访问Foo::PublicBar::x
struct X { ... }
现在是C ++中class X { public: ... }
的同义词。工会领域也是公开的。
在您的情况下,您可以通过以下方式隐藏它:
class Base {
protected:
union X {
struct {
bool bBold : 1;
bool bFakeBold : 1;
};
int a;
};
X x;
public:
bool isBold() {
return x.bBold;
}
};
现在x
是私有的,内部联合的定义不会“泄漏”到公众中。