Professional C__ - Marc Gregoire [62]
Commenting to Explain Usage
One reason to use comments is to explain how clients should interact with the code. Each publicly accessible function or method in a header file should have a comment explaining what it does. Some organizations prefer to formalize these comments by explicitly listing the purpose of each method, what its arguments are, what values it returns, and possible exceptions it can throw.
Providing a comment with public methods accomplishes two things. First, you are given the opportunity to state, in English, anything that you can’t state in code. For example, there’s really no way in C++ code to indicate that the saveRecord() method of a database object can only be called after the openDatabase() method is called. A comment, however, can be the perfect place to note this restriction, as follows.
/*
* saveRecord()
*
* Saves the given record to the database.
*
* This method will throw a "DatabaseNotOpenedException"
* if the openDatabase() method was not called first.
*/
The second effect of a comment on a public method can be to state usage information. The C++ language forces you to specify the return type of a method, but it does not provide a way for you to say what the returned value actually represents. For example, the declaration of the saveRecord() method may indicate that it returns an int, but the client reading that declaration wouldn’t know what the int means. Other ancillary data can be included in a comment as well, as shown in the following.
/*
* saveRecord()
*
* Saves the given record to the database.
*
* Parameters:
* Record& rec: the record to save to the database.
* Returns: int
* An integer representing the ID of the saved record.
* Throws:
* DatabaseNotOpenedException if the openDatabase() method was not
* called first.
*/
Sometimes, the parameters to, and the return type from a function are generic and can be used to pass all kinds of information. In that case you need to clearly document what exact type is being passed. For example, message handlers in Windows accept two parameters, LPARAM and WPARAM, and can return an LRESULT. All three can be used to pass anything you like, but you cannot change the type of them. By using type casting, they can for example be used to pass a simple integer or to pass a pointer to some object. Your documentation could look as follows.
* Parameters:
* WPARAM wParam: (WPARAM)(int): An integer representing an ID.
* LPARAM lParam: (LPARAM)(string*): A string representing...
* Returns: (LRESULT)(Record*)
* A pointer to a Record object or nullptr in case of an error.
Most editors allow you to bind keystrokes to perform certain actions. You could bind a keystroke so that the editor automatically inserts a standard commenting block which you subsequently fill in with the right information. For example, the keystroke could automatically insert the following comment template.
/*
* func()
*
* Description of the function.
*
* Parameters:
* int param1: parameter 1.
* Returns: int
* An integer representing...
* Throws:
* Exception1 if...
* Notes:
* Additional notes...
*/
Commenting to Explain Complicated Code
Good comments are also important inside the actual source code. In a simple program that processes input from the user and writes a result to the console, it is probably easy to read through and understand all of the code. In the professional world, however, you will often need to write code that is algorithmically complex or too esoteric to understand simply by inspection.
Consider the code that follows. It is well written, but it may not be immediately apparent what it is doing. You might recognize the algorithm if you have seen it before, but a newcomer probably wouldn’t understand the way the code works.
void sort(int inArray[], int inSize)
{
for (int