class 封装到命名空间后,友元函数不能再访问 class 的私有数据成员

Friend function can no longer access private data members of class after class is encapsulated in namespace

我有一个 class 封装在命名空间中的 Circle。

namespace my_name_space {
    class Circle;
}

class my_name_space::Circle {
private:
    double radius;
public:
    friend std::ostream& operator << (std::ostream &os, const Circle &c);
};

实现文件中的函数如下:

std::ostream& operator << (std::ostream &os, const Circle &c)
{
    os << "Radius: " << c.radius;

    return os;
}

在命名空间中封装 class 之前,一切正常。现在 friend 函数不能再访问私有数据成员。我不明白这是怎么回事。

当您将 operator << 声明为 Circlefriend 时,它将成为 Circle 最内层封闭命名空间的成员。这意味着当您将 Circle 放入命名空间 my_name_space 时,operator << 也会成为命名空间 my_name_space 的成员。 operator<< 的定义与此不匹配,它在全局范围内定义了 operator<<

A name first declared in a friend declaration within class or class template X becomes a member of the innermost enclosing namespace of X

您可以将 operator<< 的定义移动到命名空间 my_name_space:

namespace my_name_space {
    std::ostream& operator << (std::ostream &os, const Circle &c) {
        ...
    }
}

或者如果您仍想在全局范围内保留 operator<<

// delcaration
std::ostream& operator << (std::ostream &os, const my_name_space::Circle &c);
class my_name_space::Circle {
    ...
    friend std::ostream& ::operator << (std::ostream &os, const Circle &c);
    //                   ~~
};
// definition
std::ostream& operator << (std::ostream &os, const my_name_space::Circle &c) {
    ...
}