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

问题描述:

可能重复:
why private value of the obj can be changed by class instance?为什么==超载可以访问参数的私有成员

考虑以下(部分)代码:

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,但是不是这样的访问无效吗?

+1

出了什么问题'回报g.id ==这个 - > id'? – sbi

+1

在附注中,我认为用户名“WeaklyTyped”非常好地匹配了这个问题。 – datenwolf

+1

@sbi - 它有一个不需要的'this->'。 –

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

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

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

+0

谢谢!为解释。 – WeaklyTyped

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

如果你试图把它写成一个免费的功能,那也不会编译:

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

访问预选赛不控制在实例级别的访问,但在类型级别。 T类型实例的任何成员函数都可以访问同一类型T的任何其他实例的所有私有成员。

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

+0

我明白你的观点,但是如果你能指出为什么说明符在类型级别而不是实例级别上运行,我将非常感激。一定有一个原因。 – WeaklyTyped

+1

@ WeaklyTyped如果它们没有在类型级别上运行,那么您将无法复制构造或分配,除非所有数据都是公开的,或者每个数据成员都有“getters”。 – juanchopanza

+0

@WeaklyTyped:因为C++是一种静态类型检查语言,不可能静态确定访问是否保留在实例中(停止问题)。以成员函数'class T {private:int bar; public:void foo(T * t){t * = t-> bar;} void spam(){foo(this);}' - foo可以从类的“外部”或内部使用'这个'指针。在编译时,不可能静态检查是否发生这种情况。另外juanchopanza说。 – datenwolf