为什么我不能从不同命名空间中的友元类更改类的私有成员?

时间:2011-05-14 16:59:50

标签: c++

我发现从朋友班访问班级的私人成员时遇到了麻烦。

保存我想要更改的私有成员的类以及进行更改的类位于不同的名称空间中。

友元类是在持有数据的类之后定义的,所以我试图在名称空间之外声明友元类。

g ++说我无法修改该成员,因为它是私有的,视觉工作室似乎认为它很好。

我在这里做一些奇怪的非标准事物吗?为什么我不能改变会员?这是一个代表我的问题的简化代码段:

struct S;

namespace N
{
    class A
    {
        int m;
    public:
        A():m(5){};
        friend struct S;
    };

}

using namespace N;

struct S
{
    A& a;
    S(A& a):a(a) {}
    void changeA(){ a.m = 9; }
};

int main()
{
    A a;
    S s(a);
    s.changeA();
}

3 个答案:

答案 0 :(得分:9)

friend struct ::S;

你真正在做什么

friend struct S;

宣布N = S(无处可定义)的朋友。

编辑:支持我的想法,即gcc行为是正确的,VC ++有一个错误。

7.3.1.2/3

  

如果非本地类中的friend声明首先声明一个类或   函数friend类或函数是最里面的成员   封闭命名空间。 [...]在寻找先前的声明时   由朋友声明引入的类或函数,范围以外的   不考虑最里面的封闭命名空间范围。

答案 1 :(得分:5)

因为friend struct S;声明了N::S类,但您需要::S类。

答案 2 :(得分:4)

尝试写出friend struct ::S;

目前,假设不存在N::S。此修复程序指定全局命名空间,有点像Linux路径上的前导/指定文件系统根目录。