[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