2010-08-21 117 views
16

此代码编译关于获取封闭类的保护构件MSVC /克++:嵌套类:从嵌套保护的类

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

杜佩尔问题。不过,我现在不会去寻找原作。 :) – 2010-08-21 15:17:31

回答

13

在C++ 03标准,11.8p1表示:

嵌套类的成员具有一种封闭类的成员没有特殊的访问。

然而,对于defect report 45分辨率(与标准)状态相反,并且因此定义了行为你看到:

嵌套类是一个部件,因此具有相同的访问作为任何其他成员的权利。

在C++ 0x中的11.8文本已更改为反映这一事实,所以这是两个C++ 03和C++ 0x中标准的编译器的有效行为。

另请参见cprogramming.com论坛中的this thread

+2

+1很好的答案。然而,如果你google了这个,有一些IBM XL编译器文档只提到你说的第一部分,并暗示OP的代码不会编译。因此,在C++ 0x被广泛实现之前,目前要做的便携式事情就是将嵌套类声明为封闭类中的朋友。 – Praetorian 2010-08-21 15:23:30

+0

好找。为了完整起见,链接会很好。 :) – 2010-08-21 15:45:13

+0

我之前很懒惰:-),这里是链接。 http://publib.boulder.ibm.com/infocenter/comphelp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.aix.doc/language_ref/cplr061.html – Praetorian 2010-08-21 15:58:34

0

请参阅$ 9.7/1。

“嵌套类位于其封闭类的范围内,除了使用显式指针,引用和对象名外,嵌套类中的声明只能使用封闭类中的 类型名称,静态成员和枚举数“。

5

我没有的C++ 03得心应手副本,但是从的C++ 0x草案(n3090):

11.8嵌套类

嵌套类 是成员,因此与其他任何成员具有相同的 访问权限。封闭类的 成员对嵌套的 类的成员没有 特殊访问;应遵守通常的访问规则(条款 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苹果)与-Wall -ansi -pedantic -std=c++98和科莫(4.3.10.1)严格C +禁用C++ 0x扩展的+03模式 - 它们都似乎接受对内部类成员中的外部类private成员的访问。

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章)。