15

Possible Duplicate:
why private value of the obj can be changed by class instance?

Consider the following (partial) code:

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;
}

The code compiles and results seem proper. However, in the if part of the operator overloading implementation, we are directly accessing the private member of its argument - const Group& g, but isn't such an access invalid?

Community
  • 1
  • 1
WeaklyTyped
  • 1,331
  • 4
  • 16
  • 31

3 Answers3

24

Your operator== is a member of your Group class. Member functions can access any private members of that class, not only for this, but for any instance they can access.

If you think about it this behaviour is necessary, because otherwise access control would make methods for interaction of two or more instances (swap, copy constructors, operators) impossible, unless the object has a public accessor to any member variable, which is used in such a method. Often enough that isn't desirable from a design point of view. Furthermore it would raise the bar for access control to high ("if I simply make that member public, I can spare me the pain...").

Concluding this code is perfectly valid (although I don't see why the if is necessary, compared to simply using return g.id == this->id;)

sbi
  • 219,715
  • 46
  • 258
  • 445
Grizzly
  • 19,595
  • 4
  • 60
  • 78
16

Access qualifiers are not controlling access on the instance level, but on the type level. Any member function of a instance of type T can access all the private members of any other instance of the very same type T.

Since the operator== is a member function it can access all the member variables of instances of the class it's member of.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • I get your point, but I would really appreciate if you can point out as to why do specifiers operate at Type Level and not instance level? There must be a reason. – WeaklyTyped Sep 18 '12 at 15:19
  • 1
    @WeaklyTyped if they didn't operate at the type level, you wouldn't be able to copy construct or assign unless all data were public or there were "getters" for every single data member. – juanchopanza Sep 18 '12 at 15:29
  • 1
    @WeaklyTyped: Because C++ is a statically type checked language and it is impossible to statically determine if the access remains within the instance (Halting Problem). Take for example the member function `class T{private: int bar; public: void foo(T *t){t *= t->bar;} void spam(){foo(this);}` – foo could be called from either "outside" the class or from the inside using the `this` pointer. At compilation time it is impossible to statically check if this happens, or not. Also what juanchopanza said. – datenwolf Sep 18 '12 at 15:31
  • Thanks! That makes things pretty clear. :) – WeaklyTyped Sep 18 '12 at 15:34
6

No, because operator== is a member of Group. It's right there in the function name. That means it can access the private members of any object of that class.

If you tried to write it as a free function, that would not have compiled:

bool areEqual(const Group& g1, const Group& g2) {
    return g1.id == g2.id;
}
Jon
  • 428,835
  • 81
  • 738
  • 806