20

I just noticed something that I've never realised before. It turns out that this class is valid in C#:

class Foo
{
    private string contents;

    public Foo(string str) {
        contents = str;
    }

    public void set(Foo other)
    {
        contents = other.contents;
    }
}

So different instances of the same class can access the private members of each other.

Up til now, I thought that the private members of an object could only be accessed by that object, not by other instances of the same class. It's a little suprising to find this out.

Is this the case in all common object oriented languages? It's not intuitive for me.

japreiss
  • 11,111
  • 2
  • 40
  • 77
Oliver
  • 11,297
  • 18
  • 71
  • 121
  • It turns out someone already asked a pretty similar question: http://stackoverflow.com/questions/346127/access-private-member-variable-of-the-class-using-its-object-instance?rq=1 . The answers to that one don't give an authoritive reason for this design choice, though. Is it just because doing it differently is inefficient/impossible? – Oliver Sep 10 '12 at 16:07

3 Answers3

17

This is the same as in C++ and Java: access control works on per-class basis, not on per-object basis.

In C++, Java and C# access control is implemented as a static, compile-time feature. This way it doesn't give any run time overhead. Only per-class control can be implemented that way.

piokuc
  • 25,594
  • 11
  • 72
  • 102
  • 1
    Why is this the case? Can't the compiler just forbid calling a private method on anything other than the (implicit or explicit) `this` reference? It would mean that private methods can't be called on other variables that happen to refer to `this`, but I don't see any disadvantage of that. I think japreiss's answer is more correct. – herman Jul 12 '13 at 00:58
14

How would you make a copy constructor for a class that does not expose all of its internal state through public methods?

Consider something like this:

class Car
{
public:
    void accelerate(double desiredVelocity);
    double velocity() const;
private:
    Engine myEngine;
};

The Car's public interface doesn't expose its Engine, but you need it to make a copy.

japreiss
  • 11,111
  • 2
  • 40
  • 77
  • Yes; this. There would be no other decent way to make copy/clone methods. You could make it protected internal if you were concerned about it somehow being accessed outside the assembly or something. – Nikki9696 Sep 10 '12 at 17:15
  • 1
    It's also necessary for implementing equals(). – herman Jul 12 '13 at 01:00
1

For the exact same scenario there is 'Object specific Private' in Scala vs 'Class specific Private' which is not supported in Java also.

class Foo {

  private[this] def contents // [this] marks the property as private to the owner

  def doFoo(other: Foo) {
    if (other.contents) { // this line won't compile
      // ...
    }
  }

}

This came as a surprise that such feature is not supported in other modern languages private[this] vs private, I understand this may be not a security risk as such considering it's still tied to the Class and you can still access all the private variables with reflection either way for eg Does reflection breaks the idea of private methods, because private methods can be access outside of the class?.

If you look at from Python language perspective, they don't even have scope feature as broad as in C#, in the end it is all about code organization, and from language design perspective it's the learning curve a new comer has to go through

skjagini
  • 3,142
  • 5
  • 34
  • 63