0
class test {
public:
test(int value = 0): x(value) {}
int& get(){
    return x;
}
private:
int x;
};

this will allow client code to mutate the private members
this is legal in C++, but why ?
Is there any situation where you would actually need to break the class encapsulation ?

Aycan Yaşıt
  • 2,106
  • 4
  • 34
  • 40
Moha the almighty camel
  • 4,327
  • 4
  • 30
  • 53
  • 1
    Containers often use it so that indexing into the container behaves naturally. – Michael Burr Nov 17 '13 at 08:34
  • 1
    See http://stackoverflow.com/questions/4706788/why-can-i-expose-private-members-when-i-return-a-reference-from-a-public-member – Maroun Nov 17 '13 at 08:35
  • 3
    You didn't break encapsulation. There is nothing stopping you, the coder of `class test`, from changing the game and the backend of what serves up that reference. Users of your code still get a hot-int-reference, *which you chose to expose*. If you don't want to do that, frankly, *don't*. – WhozCraig Nov 17 '13 at 08:38
  • 1
    "Why" This is a language specification. You can better ask C++ inventor. –  Nov 17 '13 at 08:38
  • Related question: http://stackoverflow.com/q/18865500/1782465 – Angew is no longer proud of SO Nov 17 '13 at 08:56

3 Answers3

3

Make a member as private, means you can not access it directly. But nothing restricts you to access it indirectly via a public member. It depends on you design. You can even do this:

class test {
public:
   test() : x(y) {}
   int &x;
private:
   int y;
};

In your class, assume you want count how many times a member is read/write. So, you can make it private then put a member function which returns a refernce to the variable:

class test {
public:
  test(int value = 0): x(value), count(0) {}
  int& get(){
      count++;
      return x;
  }
private:
  int x;
  int count;
};

I hope this example shows how making a member as private and then putting an indirect access to it can be useful.

masoud
  • 55,379
  • 16
  • 141
  • 208
2

Ffirst of all let's consider implementing what you describe. It would be very onerous to properly do so. Your example is easy enough. But what if the reference flowed through a number of functions before it reached the function that exposed it? The compiler would have to do exceptionally complex static analysis, beyond the levels of static analysis that are reasonable to expect from compiler writers.

So even if the designers wanted to ban this, it would not have been tractable to do so. Would the designers have wanted to stop this? Very doubtful. Had they done so, how would the [] operator be implemented on a container or a string?

Is there any situation where you would actually need to break the class encapsulation

As example of the [] operator on containers and strings shows, this feature is in fact used to support encapsulation.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • `operator[]` on standard containers doesn't return a reference to a private member. It returns a reference to an object which is pointed to (directly or indirectly) by a private member. – Benjamin Lindley Nov 17 '13 at 09:03
  • and that may be a technicality, but I think it's an important distinction in this case, because what `operator[]` does is actually useful, and it's a little more difficult (but not impossible) to find a useful example that actually *does* return a reference to a private member. – Benjamin Lindley Nov 17 '13 at 09:09
1

Why? Because C++ mainly tries to let you do whatever you want and not get in your way; it doesn't try very hard to keep you safe. If you want a safe language, use something else. You have something like object-orientation if you want to, but if you want to break out of that, more power to you. With great power comes great responsibility.

It's worth nothing that you don't even need this to break encapsulation; you could simply reinterpret a pointer to "test" as an integer and access the private field this way.

Asik
  • 21,506
  • 6
  • 72
  • 131