为什么 == 重载可以访问参数的私有成员

Why == overloading can access private members of argument

本文关键字:成员 参数 访问 重载 为什么      更新时间:2023-10-16

可能的重复项:
为什么 OBJ 的私有值可以通过类实例更改?

请考虑以下(部分)代码:

class Group {
    private:
      int id;
    public:
      void set_id(int);
      int get_id();
      bool operator==(const Group&);
};

bool Group::operator==(const Group& g) {
    if(g.id == this->id) {  /* id is private? */
            return true;
    }
    return false;
}

代码编译和结果似乎正确。但是,在运算符重载实现的if部分,我们直接访问其参数的私有成员 - const Group& g ,但这样的访问不是无效吗?

您的operator==Group类的成员。 成员函数可以访问该类的任何private成员,不仅对于this,而且对于它们可以访问的任何实例。

如果你考虑一下,这种行为是必要的,因为否则访问控制将使两个或多个实例(swap,复制构造函数,运算符)的交互方法变得不可能,除非对象具有任何成员变量的公共访问器,这在这种方法中使用。从设计的角度来看,这通常是不可取的。此外,它将把访问控制的标准提高到很高("如果我只是让该成员公开,我可以免除我的痛苦......")。

总结这段代码是完全有效的(尽管与简单地使用 return g.id == this->id; 相比,我不明白为什么if是必要的)

访问限定符不是在实例级别控制访问,而是在类型级别控制访问。类型 T 的实例的任何成员函数都可以访问同一类型 T 的任何其他实例的所有私有成员。

由于 operator== 是一个成员函数,因此它可以访问其所属类实例的所有成员变量。

不,因为operator==Group的成员。它就在函数名称中。这意味着它可以访问该类的任何对象的private成员。

如果你试图把它写成一个自由函数,那不会编译:

bool areEqual(const Group& g1, const Group& g2) {
    return g1.id == g2.id;
}