我有以下代码,其中A类将B类声明为朋友。在类B中声明的类C是否能够查看类A的私有声明/成员?
它与CL版本16(Visual Studio 2010)一起编译时没有错误,但是gcc g ++版本4.1.1给出了错误“typedef int A :: T在此上下文中是私有的”。
函数调用为typedef会发生同样的行为(这就是我发现差异的方法)。
class A {
friend class B;
typedef int T;
};
class B {
A::T t; // ok
typedef A::T U; // ok
class C {
U u; // ok
A::T v; // compile error on gcc
};
};
我已经简单地查看了,但未能找到正确的搜索字词。我还没读完标准。以前有关于这个主题的问题,或者在C ++ FAQ中提到过吗?标准是否会影响哪种行为,如果有的话?
答案 0 :(得分:9)
来自标准文档。$11.4.2
声明一个班级成为朋友意味着该班级的私人和受保护成员的姓名授予友谊 可以在友情类的基本说明符和成员声明中访问。
标准文档中的一个例子,本身,
class A {
class B { };
friend class X;
};
struct X : A::B { // OK: A::B accessible to friend
A::B mx; // OK: A::B accessible to member of friend
class Y {
A::B my; // OK: A::B accessible to nested member of friend
};
};
因此它应该没有任何错误。
答案 1 :(得分:4)
似乎有some defect in the original standard C++03
根据C ++ 03 [pre CD1],您的代码不应该编译,因为措辞和示例说明无法在友元类的嵌套成员中访问类的私有成员(授予友谊)。
C ++ 11给出了与C ++ 03中相同的例子。对该示例进行的唯一更改是,友元类的嵌套成员(类)能够访问授予友谊的类的私有成员。
声明一个类成为朋友意味着可以在友好类的基本说明符和成员声明中访问授予友谊的类中的私有成员和受保护成员的名称。
另请参阅issue #45
答案 2 :(得分:1)
Prasoon提到问题#45 ......这种行为在C ++ 0x中发生了变化。旧的行为是(11.7 [class.access.nest]
第1段):
嵌套类的成员对封闭类的成员没有特殊访问权限,也没有对已经为封闭类授予友谊的类或函数的特殊访问权。
这清楚地表明gcc 4.1根据C ++ 03规则是正确的。 gcc 4.5和MSVC2010正在使用C ++ 0x规则。