13

可能重复:
为什么类实例可以更改 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,但是这样的访问不是无效的吗?

4

3 回答 3

23

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

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

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

于 2012-09-18T15:14:09.563 回答
16

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

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

于 2012-09-18T15:13:40.763 回答
6

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

如果您尝试将其编写为自由函数,则不会编译:

bool areEqual(const Group& g1, const Group& g2) {
    return g1.id == g2.id;
}
于 2012-09-18T15:13:01.563 回答