[Tutor] Slightly OT: public/private class members
Erik Price
eprice@ptc.com
Fri Feb 14 11:35:03 2003
pcarey@lexmark.com wrote:
> Hello.
> I'm only in my second C++ class at the local university, but I've been
> using Python for a while. We are just now beginning to create C++ programs
> that use classes. My prof says "99% of all data members of a class should
> be private" in a quasi-brainwashed kind of way. My question is thus:
> when/why would data members/methods need to be private? I know python has
> adopted a "we're all consenting adults" point of view (cannot remember
> where I read that). I rather like that point of view, and dislike creating
> all these "get & set" methods to fetch/set data members from an object.
>
> So, what's the need/use for private members?
It ensures that client code only accesses or changes data in your object
through methods that you have explicitly provided. You can ensure that
objects are immutable in this fashion, you can ensure that only one
instance of an object is every created in this fashion (singleton
w/public factory method and private constructor).
A good example is just recently, on this very list, someone wanted to
create a list (or dictionary? I forget) that they could tell when it had
been recently modified, so that they could avoid iterating over the list
unnecessarily. (Or something like that.)
Here is the class:
class TimeSensitiveList():
def __init__(self):
self._private_list = []
self._private_modified = false
def _private_check_is_modified(self):
"Determine if the list has been modified since last access"
return self._private_modified
def append(self, item):
"append an item to the list"
self._private_modified = true
return self._private_list.append(item)
def some_complex_function(self):
"perform some complex function only if the list has been modified"
if not self._private_modified:
do some complex function
self._private_modified = false # reset the flag
Actually, in the OP's case it was a dictionary, not a list, and the
thread is called "Checksum of a dictionary". But you can see how, if
the private methods (prefixed by "_private_" in my example) are
uncallable from the client code, and assuming that the programmer has
been careful, there is no way to access the data in the dictionary
without tripping the "modified" flag.
That's the idea and reasoning behind it. It is especially important
when you are distributing code that may be used by others, which you
will have to be responsible for maintaining, because if at a later date
you decide to change the class (for performance enhancements or
something), then you will want to make sure that the class still works
with any client code that is making use of it. This means that you
should leave the public API alone (since that is what client code is
depending on not to change) and only modify the private methods. Since
no client code could possibly be dependent on the private methods
(they're private, after all), you can do whatever you need to those.
One of the tips from Joshua Bloch's "Effective Java" (an incredible book
IMHO if you are a Java programmer) is to try to keep as many of your
members private as possible, because for every member you make public,
you are now responsible for maintaining one more facet of your class.
In other words, private members help encapsulate the logic of a class so
that it is a "black box" that is not tampered with by client code.
Erik