class private_object
{
private:
struct make_public;
friend struct make_public;
static void method1() {}
};
struct private_object::make_public
{
class nested_outer
{
void callFromOuter()
{ private_object::method1(); } // Should this be an error?
class nested_inner
{
void callFromInner()
{ private_object::method1(); } // How about this one?
};
};
};
当我试图将一个开源项目移植到borland下编译时,这个友谊问题出现了。根据{{3}}和两个半相关问题parashift和here,上述示例不应有效。
然而,在七个不同的编译器 1 上测试后,只有borland和dmc抱怨。这种行为让我感到惊讶,因为我并不认为友谊会在嵌套类中传递。
所以这提出了几个问题:
<子> 1。测试了mingw-gcc 4.5.2,clang,borland c ++ builder2007,数字火星,开放式watcom,visualc2010和comeau online
答案 0 :(得分:3)
在C ++ 03中,嵌套类默认情况下不能访问封闭类的private
和protected
成员(参见§11.8/ 1)。但如果你让他们成为封闭类的朋友,那么他们就可以访问它们。但是嵌套类的嵌套类仍然不是最外层封闭类的朋友,嵌套类的嵌套类不能访问最外层封闭类的私有和受保护成员;如前所述,它甚至无法访问直接封闭类的私有和受保护成员。你正在做的是,因此这是不允许的。
C ++标准版(2003)以11.8美元/ 1 [class.access.nest]的形式说,
嵌套类的成员没有 特殊访问成员 封闭类,也不包括类或 授予友谊的功能 到一个封闭的班级;通常 准入规则(第11条)应为 服从。 封闭的成员 class没有特殊的访问权限 嵌套类的成员; 通常的 准入规则(第11条)应为 服从。
标准本身的例子:
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
}
};
顺便说一句,它是C ++ 03标准中的缺陷。由于嵌套类是成员,因此它应该可以访问私有成员和受保护成员,就像任何其他成员一样:
§9.2/ 1(C ++ 03):
类的成员是数据成员,成员函数(9.3),嵌套类型 ...嵌套类型是类(9.1,9.7)和类中定义的枚举(7.2)...
请参阅缺陷报告:
答案 1 :(得分:1)
我不知何故觉得这应该是允许。虽然我不确定标准行为。有人可以指出。
对于拒绝此代码的编译器, 什么是合适的 解决办法:
我能想到的最好是做一个包装器:
struct private_object::make_public
{
static void wrap_method1() { private_object::method1(); }
// use wrap_method1() everywhere else
// ...
};