此代码在msvc / g ++上编译:
class A{
protected:
int i;
class B{
public:
A* a;
B(A* a_)
:a(a_){
}
void doSomething(){
if (a)
a->i = 0;//<---- this part
}
};
public:
A()
:i(0){
}
};
正如您所看到的,B可以访问封闭类的“受保护”部分,尽管它未被声明为朋友。
这是一种标准(符合标准)的行为吗?
我有时使用此功能,但我不记得规则说嵌套的受保护类应该自动访问封闭类的所有受保护数据。
答案 0 :(得分:14)
在C ++ 03标准中,11.8p1说:
嵌套类的成员对封闭类的成员没有特殊访问权限。
然而,defect report 45(对标准)的分辨率却相反,因此定义了您所看到的行为:
嵌套类是一个成员,因此具有与任何其他成员相同的访问权限。
在C ++ 0x中,11.8的文本已被更改以反映这一事实,因此这对符合C ++ 03和C ++ 0x的编译器都是有效的行为。
另请参阅this thread论坛中的cprogramming.com。
答案 1 :(得分:5)
我没有C ++ 03的副本,但是来自C ++ 0x的草稿(n3090):
11.8嵌套类
1 嵌套类 是会员,因此也是如此 作为任何其他成员的访问权限。该 附上课程的成员没有 对嵌套成员的特殊访问权限 类;通常的访问规则(条款 11)应遵守。
[例如:
class E {
int x;
class B { };
class I {
B b; // OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
};
int g(I* p) {
return p->y; // error: I::y is private
}
};
因此,至少在下一个标准中,封闭类可以像任何普通成员函数那样访问外部类的成员。
更新:当前标准中不允许这样做。但是提交了一份缺陷报告(DR 45)来解决这个问题。 (SigTerm的编辑把这个拿出来了。请小心。)
更新#2:我尝试使用VS2010,g ++(4.0.1 Apple)与-Wall -ansi -pedantic -std=c++98
和Comeau(4.3.10.1)在严格的C ++ 03模式下禁用C ++ 0x扩展 - 所有它们似乎接受对内部类成员中外部类private
成员的访问。
答案 2 :(得分:0)
参考$ 9.7 / 1。
“嵌套类在其封闭类的范围内。除了使用显式指针,引用和对象名称之外,嵌套类中的声明只能使用 封闭类中的类型名称,静态成员和枚举器。“
答案 3 :(得分:0)
这是一种标准的(符合标准的)行为吗?
否即可。
根据C ++ - 2003
Section 11.8.1
嵌套类
嵌套类的成员对封闭类的成员没有特殊访问权限,也没有对已经为封闭类授予友谊的类或函数;应遵守通常的准入规则(第11条)。封闭类的成员对嵌套类的成员没有特殊访问权限;应遵守通常的准入规则(第11条)。
[Example:
class E {
int x;
class B { };
class I {
B b; //error: E::B is private
int y;
void f(E* p, int i)
{
p->x = i; //error: E::x is private
}
};
int g(I* p)
{
return p->y; //error: I::y is private
}
};
—end example]
但ISO/IEC N 3092
中对该部分进行了轻微修改,其中说
嵌套类是成员,因此具有与任何其他成员相同的访问权限。封闭类的成员对嵌套类的成员没有特殊访问权限;应遵守通常的访问规则(第11条)。