2011-05-12 75 views
14

我有以下代码,其中类A声明类B为朋友。在B类中声明的C类是否应该能够查看A类的私人声明/成员?一个类的“朋友”是否扩展到该类中声明的类?

它使用CL版本16(Visual Studio 2010)编译没有错误,但gcc g ++版本4.1.1给出了错误“typedef int A :: T在此上下文中是私有的”。

函数调用发生的行为与typedefs相同(这是我发现的区别)。

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

请参阅http://stackoverflow.com/questions/3584385/friend-access-to-protected-nested-class。 – 2011-05-12 08:39:52

+0

这段代码看起来很适合我。获取gcc 4.5.1和在线上的comeau编译。 – 2011-05-12 08:45:24

+0

Prasoon:呵呵。我想知道为什么我的gcc过时了,它应该是新安装的。好吧。谢谢! – 2011-05-12 09:00:04

回答

9

从标准文档,$11.4.2

声明一个类是朋友意味着private和protected成员从类授予友谊名 可以在基本符S和成员进行访问声明友谊班。

从标准文档的例子中,自身,

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

因此它应该工作而没有任何错误。

+0

谢谢!看起来对我来说是authoratative。 – 2011-05-12 08:59:35

+0

也请看[this](http://stackoverflow.com/questions/5975421/does-friending-a-class-extend-to-classes-declared-within-that-c​​lass/5975757#5975757)回答。 – 2011-05-12 09:20:57

4

似乎有some defect in the original standard C++03

按照C++ 03 [预CD1]你的代码不应该编译,因为措辞和例子说,一个班(授予友谊)的私有成员不能在访问朋友类的嵌套成员。

C++ 11给出了与C++ 03中相同的示例。对这个例子唯一的改变是朋友类的嵌套成员(类)能够访问授予友谊的类的私有成员。

声明一个类是一个朋友意味着来自授予友谊的类的私有和受保护成员的名字可以在友谊类的基本说明符和成员声明中访问。

也期待在issue #45

+0

啊!再次感谢你。 – 2011-05-12 09:25:08

0

Prasoon提到的问题#45 ...中的C++ 0x这种行为的改变。旧的行为(11.7 [class.access.nest]第1款):

嵌套类的成员有一个封闭类的成员没有特殊的访问,也不限于已授予友谊的封闭类的类或函数。

这清楚地表明,根据C++ 03规则,gcc 4.1是正确的。 gcc 4.5和MSVC2010使用C++ 0x规则。