Is there a best sequence for sections of a class definition?

A Mild Dissent from a Growing Practice in C++

Conrad Weisert, Information Disciplines, Inc., 29 January 1999

More and more "C++ Coding Standards" documents are calling for placing the public section of a class (the interface methods) before the private section (mainly the member data items) in a class definition. That practice has also been picked up by a number of textbooks, reversing the common convention of a few years ago.

I've tried to discern a rationale for the change, but rarely is one stated. When an author does state a reason, the one we keep hearing is awfully disturbing. One standards manual says:

"For the reader of a class, the public interface is the most important aspect and therefore must come first."

So, who are the "readers"? Are readers and users really the same audience?

The expectation here seems to be that we're not going to prepare any sort of user documentation for our classes, and that a potential user is going to have to consult our source code in order to find out what our class does and how to use it. Furthermore, we want to make it as hard as possible for the user to learn about our hidden member data, and putting those declarations at the end contributes (in a very small way) to that goal!.

Well, if that's the main reason justifying this growing convention, count me out. The designer of an OOP class, like the designer of any software component, is responsible for telling potential users of that component what it does and how to use it.

For decades we've been putting reusable subroutines in component libraries, expecting the users to gain access to the compiled object module. Rarely would a user need to consult the original source code.

Similarly, the user or potential user of our class has no business reading the source code at all, unless he or she is curious about our implementation. That user should be able to find out everything needed to use our class by consulting the user documentation we prepare. Few of the standards drafters, I'm sure, learned to use ostreams by reading iostream.h.

The most likely reader of any piece of code is the maintenance programmer who wants to add or modify functionality or to trouble-shoot a suspected bug. It is that reader whom we must cater to in writing readable easy-to maintain C++ code.

On the other side of the argument are several considerations:
  • In every other context, data items appear at the beginning of their scope. The reader who wants to understand the internals of our class is alsmost certain to want to see the member data first.
  • Functions defined inside the class definition usually refer to the member data items. Although C++ now permits them to refer to later-declared data, it's much more natural for the reader to have already seen them. (And yes, I know that many of the same standards manuals also prohibit function definitions inside the class definition, and I'll address that in a separate article. Since Java actually requires function definitions inside the class definition, that practice is staging a comeback.)
  • Students and C++ neophytes find the older convention easier to grasp in course handouts and examples.
  • Stroustrup and the other language designers expected the private sections to come first, since they made private the default access specifier for class.

Update, June, 2004 -- another reason

Herb Sutter and Jim Hysop described1 a technique whereby a malicious or uncooperative client programmer can gain access to private class members, like this:

   #define private public
         #include "classdefn.h"
   #undef private 
While mature programmers deplore such cheating, they can easily thwart it by staying with the older convention.
As the title indicates, this is hardly a life-or-death issue. When I work on a project that strongly favors the public-first convention, I follow it, too for any new classes I develop. But when I draw an existing class from the IDI library I expect others on the project team to be equally tolerant.

1 -- "Getting Abstractions", C/C++ User's Journal, June 2004, p. 58.

Return to technical articles
REturn to IDI home page