Wednesday, November 17, 2004

Trespassers will be prosecuted (unless you belong to same class)

I came across a big surprise yesterday. I was reading a book on C++ (Stanley Lippman's C++ Primer) and came across the fact that (in C++) objects made from the same class can access each other's private members. I kinda felt ashamed that I didnt know this fact till now. I was much surprised also, since it seemed quite counter-intuitive. But I am not a person who would argue with Stanley Lippman ;-), so I accepted it in its face value. I decided to try it out later on my system.
Today I tried it out and verfied the correctness. Excited by this "new discovery" I told this fact to 3 people who has more than 5 years of experience in jave and they all said that this was not the way things are in java, and that in java you couldnt access the private member variable of another object, regardless of whether the objects belong to same class or not.
But I didnt take their statement in the same way as I did with Lipppman, I immediately tried it out and foung that they were wrong :-) An object can access the private member of another object of same class. None of them could take that in so easily. I showed them the code, compiled and executed it. They were convinced.
I found out that the access specifiers are for a class and not for individual objects. Anf if you think about it, there is actually no problem with this implementation. If an object has to access private members of another object of same class, the class author would know exactly how the interactions take place and what the implications of the interaction are.
Well, I am still surprised :-)

The programs that i tried out in C++ and java are given below :

//==================================================================================
//C++ Example
//private_mem.cpp
//==================================================================================


#include

using namespace std;

class A
{
private:
int m_a;

public:
A(int a);
int func(A& a_object);
};


A::A(int a)
{
m_a=a;
};

int A::func(A& a_object)
{
//access member variable of another object
return a_object.m_a;
};


int main()
{
A a(10);
A b(20);
a.func(b);
return 0;
}

//==================================================================================
//Java Example
//myClass.java
//==================================================================================

class testClass
{
private int x;

public void print(testClass testObject)
{
//access member variable of another object
System.out.println(testObject.x);
}
}


class myClass
{
public static void main(String args[])
{
testClass a = new testClass();
testClass b = new testClass();
a.print(b);
}
}


3 Comments:

Blogger Vineeth said...

I was really surprised and checked up the Java lang spec. Interesting all scope definitions are for class and not for Objects.

It seems that Ruby is not taking this path and I would assume that Smalltalk won't either

11/17/2004 07:00:00 PM  
Blogger PC said...

A friend brought to my notice that this was something that we did in Java and C++ quite frequently but didnt actually think about, for eg. while overriding Clone() of Cloneable interface for a Java class or while writing copy constructor for a C++ class.

11/18/2004 11:15:00 AM  
Blogger Vikas S Nair said...

This might be of help...

Definition: "Per-Class Encapsulation" gives a method of class X direct
access to any object which is known to be of class X ("direct access"
means the ability to access the private parts of an object without
going through some access method).

Definition: "Per-Object Encapsulation" gives a method of class X
direct access to the this (or self) object, but denies the method
direct access to any other X objects (such as to parameter-objects).

Consider the following copyFrom method as prototypical of methods that
accept another object of their class as a parameter (in C++, these
would be called the copy constructor and assignment operator):

//pigin C++

class Stack {
public:
//...

getNumElems()
{
//This "get" method belongs in the public /interface since:
// (1) it doesn't expose the implementation technique, and
// (2) users might find it useful.
//...
}

copyFrom(const Stack& from)
{
//If copyFrom can't access "from.data" directly, it would
//need a public method to access "from.data" (such as the
//"getList()" method; see below).
//...
}

List& getList()
{
//This "get" method does not "belong" in the public
//interface (it exposes the implementation technique),
//yet per-object encapsulation would make it needed...
return data; //yuk
}

private:
List data;
};

Conclusion: Although pushing encapsulation down to the object
granularity rather than the class granularity seems to improve
encapsulation, in practice it can actually degrade encapsulation,
since it forces some classes to artifically expose their private
parts.

For the full article go to:
http://hjem.get2net.dk/nimrod/cpptips/perclass_encap

11/18/2004 02:18:00 PM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home