OO Question Regarding Private Properties

Started by
3 comments, last by Hodgman 12 years, 9 months ago
I was experimenting with some classes and inheritance and what not, and I came about this 'discovery' that somewhat made sense and at the same time was somewhat shocking. I use discovery lightly, because I don't know if this is commonly known, but I've certainly never heard of it.

If you have a class A and a class B that aren't related, then you can't access any of B's private or protected properties, correct?
class B {

public:
B() {
privateProperty = 25;
// arbitrary value for testing
}

private:
int privateProperty;

}

class A {

public:
A(B &ref_to_b) {
printf("%d\n", ref_to_b.privateProperty);
// error, can't access private property in B
}

}


However, I've found that if you instead pass a reference to an object of the same class, you can access the private properties.
class A {

public:
A() {
privateProperty = 25;
// default constructor
}

A(A &same_class) {
printf("%d\n", same_class.privateProperty);
// success, can access private property of referenced object
}

private:
int privateProperty;
}


This may be a stupid question to some of you, but I just found it somewhat bizarre as well as obvious. Is it supposed to work this way, or is it inefficient from an OO standpoint as far as extendability and maintenance goes? If that same reference "same_class" was used anywhere else but inside a method of that class, you wouldn't be able to access the private property.


Edit: So that some of you can understand why I'd be using this, I have a class with a method called "addChild" that takes a reference to an object of the same type. This class also contains a private property called "parent" that I don't want accessible outside of the class. Because the child object was of the same type, I found that I could access it's private parent property with no problem from inside the class, which was great but left me questioning whether or not it was the 'right' way.

Example:

class A {

public:
A *addChild(A &child) {
child.parent = this;
// extra code here to add the child
// to an array of children in this object
return child;
}

private:
A *parent;
// array of children here, e.g.
// A children[20]; or something
}
Advertisement
It is very clear that private members can only be accessed by member functions and friends, but a member function can access private members on any instance of the class, not just the object on which the method was called. This makes sense. The point of private members is that the code of the class is the only code that is allowed to know what the implementation details are.

It is very clear that private members can only be accessed by member functions and friends, but a member function can access private members on any instance of the class, not just the object on which the method was called. This makes sense. The point of private members is that the code of the class is the only code that is allowed to know what the implementation details are.


Thanks for the quick reply. It does make sense to me now, I guess I had just never thought about doing that before. I had always thought of a private member as only being accessed from within the same instance. This will certainly be helpful in my future projects.
It makes sense for example, in operator =, where you may be copying private data from another instance of the class.
I remember finding this interesting when I was first learning OOP as well smile.gif
It's ok to touch the privates of another instance of the same class.

The point of making things private though is largely:
A) to hide unnecessary details from the 'public interface' of a class.
B) to enforce invariants.

For example, let's say you've got the invariant that "[font="Courier New"]A::parent[/font] will never be [font="Courier New"]NULL[/font]". If you find a bug somewhere, which is caused by [font="Courier New"]parent[/font] being [font="Courier New"]NULL[/font], then thanks to [font="Courier New"]private[/font], you instantly know that the only place you have to look is in the source-code for [font="Courier New"]A[/font], as that's the only area of the code that's allowed to change the [font="Courier New"]parent[/font] variable.

This topic is closed to new replies.

Advertisement