13.7 Style

I l @ ve RuBoard

Programming style for classes looks pretty much like the style for structures and functions. Every member variable should be followed by a comment explaining it, and every member function should be commented like a function.

However, you comment the prototypes for member functions differently from normal function prototypes . For normal functions you put a full function comment block in front for the prototype. If you did this for the member functions of a class, the comments would obscure the structure of the class. This is one of the few cases when too many comments can cause trouble. So you put a one-line comment in front of each member function prototype and full comments in front of the function itself.

But what about inline-member functions, where the entire body of the function is declared inside the class? How do you comment that? If you put in full comments, you obscure the structure of the class. If you put in one-liners, you omit a lot of useful information. Proper commenting is a balancing act. You need to put in what's useful and leave out what's not.

The solution is to keep the size of the inline-member function small. There are two reasons for this: first, all inline functions should be small, and second, large functions declared inside a class make the class excessively complex. A good rule of thumb is that if the function requires more than about five lines of code, put a prototype in the class and put the body of the function elsewhere.

The structure of very small member functions should be obvious and thus not require a full-blown comment block. If the function is not obvious and requires extensive comments, you can always put in a prototype and comment the body of the function later in the program.

C++ does not require an access specifier ( public , private , or protected ) before the first member variable . The following is perfectly legal:

 class example {         int data;         // ... }; 

But what is the access protection of data ? Is it public , private , or protected ? If you put in an explicit specification, you don't have to worry about questions like this. (For those of you who are curious , the access specification defaults to private .)

Finally, C++ will automatically generate some member functions, such as the default constructor, the copy constructor, and the assignment operator. Suppose you have a class that does not specify a copy constructor, such as this:

 // Comments describing the class // Note: The style of this class leaves something to be desired class queue {     private:         int data[100];    // Data stored in the queue         int first;        // First element in the queue         int last;         // Last element in the queue     public:         queue(  );          // Initialize the queue         void put(int item);// Put an item in the queue         int get(  );    // Get an item from the queue }; 

Did the programmer who created this class forget the copy constructor? Will the copy constructor automatically generated by C++ work, or did the programmer design this class knowing that the copy constructor would never be called? These important questions are not answered by the class as written.

All classes have a default constructor, copy constructor, assignment operator, and destructor. If you do not create one of these special member functions, C++ will generate one automatically for you. If you expect to use any of these automatic functions, you should put a comment in the class to indicate the default is being used:

 // Comments describing the class class queue {     private:         int data[100];    // Data stored in the queue         int first;        // First element in the queue         int last;         // Last element in the queue     public:         queue(  );          // Initialize the queue         // queue(const queue& old_queue)          //     Use automatically generated copy constructor         // queue operator = (const queue& old_queue)         //     Use automatically generated assignment operator         // ~queue(  )         //    Use automatically generated destructor         void put(int item);// Put an item in the queue         int get(  );    // Get an item from the queue }; 

Now it is obvious what member functions the programmer wanted to let C++ generate automatically, and being obvious is very important in any programming project.

The copy constructor automatically generated by C++ is rather simple and limited. It doesn't work in all cases, as you'll see later when you start to construct more complex classes. But what happens when the automatic copy constructor won't work as you desire , and you don't want to go to the trouble to create your own? After all, you may decide that a class will never be copied (or that if it is, it's an error).

One solution is to create a dummy copy constructor that prints an error message and aborts the program:

 class no_copy {         // Body of the class     public:         // Copy constructor         no_copy(const no_copy& old_class) {             std::cerr <<              "Error: Copy constructor for 'no_copy' called. Exiting\n";             exit(8);         } }; 

This works, sort of. The problem is that errors are detected at runtime instead of compile time. You want to catch errors as soon as possible, so this solution is at best a hack.

However, you can prevent the compiler from automatically calling the copy constructor. The trick is to declare it private. That's your way of saying to the world, "Yes, there is a copy constructor, but no one can ever use it":

 class no_copy {         // Body of the class     private:         // There is no copy constructor         no_copy(const no_copy& old_class); }; 

Now when the compiler attempts to use the copy constructor, you will get an error message like "Error: Attempt to access private member function."

Note that in this example, you have defined the prototype for a copy constructor, but no body. Since this function is never called, a body is not needed.

I l @ ve RuBoard


Practical C++ Programming
Practical C Programming, 3rd Edition
ISBN: 1565923065
EAN: 2147483647
Year: 2003
Pages: 364

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net