一直以来都认为C++类里嵌套的类对于外部类的成员遵循基本的规则,该怎样还是得怎样:如果外部类成员是public的则可以访问,private或者protected则不能访问,想要访问的话只能通过声明友元。然而最近发现却不是如此,考虑下面的代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Outer {
    private:
        int a_;
    public:
        class Inner {
            public:
                void Print(Outer* o) {
                    printf("%d\n", o->a_); // 这里可以访问Outer的私有成员a_
                }   
        };  
};

上面的代码在gcc下是可以通过编译的,无论指定-std=c++03还是c++11,相当于Inner类是Outer类的友元。查了一下资料,发现C++98版本最初的规定不是这样的:

1
The members of a nested class have no special access to members of an enclosing class.

也就是说按照最初的C++98版本Inner是无法访问Outer的私有成员的,不过,C++标准委员会可能感觉哪里有些不对,提出了一个 defect report 45,推翻了原有的设定,表示嵌套类是外部类的友元:

1
A nested class is a member and as such has the same access rights as any other member.

C++11以及随后的版本都是按照这个设定,gcc的c++03版本也按照这个设定实现。但有些老的编译器可能并不支持这种写法,想要移植性的话可能需要加上友元的声明,或者直接使用支持C++11以后版本的编译器。

参考资料