C++ Coding Conventions Examples



Standards

The ISO standard was finalised in 1998 and most compilers have more or less conformed to the standard since 2002-03. The language continues to evolve with recent compilers (e.g. GCC4) starting to implement features from the first Technical Report, and with the working group begining work on a new C++0X standard. Bjarne Stroustrup's book "The C++ programming language 3rd ed." is the more or less definitive guide to the features of the C++98 standard, although it is admittedly at a rather high-level. We like Stephen Prata's "C++ primer plus" for beginners and for its practical examples.

For information relating to POSIX, the POSIX Programmers Guide may be of assistance. Information on the POSIX committee (also known as the IEEE PASC Committee) is available here while the official PASC page may also be helpful.


Layout

All code should be indented to indicate clearly the logical structure and hence the flow of execution. Also, corresponding pairs of brackets should occur in the same column to maintain visual coherency. This is especially important when dealing with nested loops where it is easy to get lost in a tangle of commands otherwise. For example, this series of three for loops is relatively easy to overlook:

for(int outer=0; outer < 30; outer++)
{
    ....
    for(int middle=0; middle < 20; middle++)
    {
    	.... 
	for(int inner=0; inner < 10; inner++)
	{
	    ....
	    code to do things
	    ....
	}
    }
} 

whereas something like this:

for(int outer=0; outer < 30; outer++;) {
    ....
    for(int middle=0; middle < 20; middle++) {
    	.... 
        for(int inner=0; inner < 10; inner++) {     
            ....
            code to do things
            ....
        }                                   
    }       
}         

while fine for the compiler is more difficult to follow.


Documentation

Each class will have HTML documentation written for it. The HTML version which is to be used will be 3.0+. This includes support for features such as tables and better text-alignment control as well as equations.


Comments

All comment lines less than four lines of text should employ the C++ // style of commenting. Class definitions and class declarations should have comment sections at the start and end of the class. The comment at the start of a class should indicate the class name, calling style, member functions and data (indicating whether these be public, private or protected). More extensive information on the class can then be included in the comments section at the end.

Any code written must be commented such that that:


Header Files

Header files should have the extension .h as final suffix.
So, for example, the following are valid filenames for header files:

	molecule.h
	my_header.h
	atom.revision_1.h

The following are not valid filenames for header files:

	molecule.hpp
	my_header.hxx
	atom.revision_1. (i.e. no extension !)
	molecule.c
	molecule.cpp
	molecule.cxx


Header files may contain the following elements, examples of which are given.

Lexical Element Example of Code Notes/Comments
Type Definitions typedef float REAL Define a type REAL which is a floating-point number
Templates List<Atom> *resatomlist; Example of class data using templates
Function Declarations Atom *GetAtom(Atom *atom); A class member function declaration
Inline Function Declarations char *GetResidueName() {return residuename;} An access function for class Residue
Data declarations empty empty
Constant Definitions e.g. const float pi = 3.14159; The keyword const redefines the word pi to mean a floating-point number whose value is set to 3.14159
Enumerations e.g. enum colour(red, green, blue}; colour c; Thus, we could specify: c=green; to set the colour
Name declarations empty empty
Include directives #include "Molecule.h" the quotes indicate a user-defined header file is to be included.
Comments // This is a comment line The C++ comment characters (//) should be used in preference over the old style (/* and */) comment characters.

Header files may not contain:

Header files will define and test a preprocessor variable X_H preventing multiple inclusion of that header file in the same translation unit:

	#if !defined(RESIDUE_H)
	#define RESIDUE_H

	...rest of code...

	#endif

Each header file will contain #include statements for all header files on which it depends:

	#include "header_file.h"

or

	#include 

for default (compiler-default) header files.


Implementation Files

All C++ files will have the extension .cpp as the final suffix. Thus the following are all valid C++ filename:

	residue.cpp
	atom.v2r1.cpp
	molecule_trial_version.cpp

By contrast, all the following are NOT valid filename:

	residue.c
	atom.cxx
	molecule.c.v1.2
	atom_trial_version.c
	my_class.cc

They may contain the following:

Method Definitions example in here !!!!!
Static class member definitions example in here !!!!!

They may not contain variables in global scope (function or class scope only).


Names

The following should be observed:

Item Example(s)
Names of templates/classes/functions to start with an uppercase letter Store<Atom>, class Atom, GetResname()
unless they are standard library extensions inverse_cholesky, numeric_vector
Only use abbreviations when they are obvious For example, GetResName is OK, but NoAtoms is too unclear !
Words within a name should start with an uppercase letter For example, AddtoResidue and GetNextAtom are both OK.
The first letter of Variable and data names should be lowercase firstAtom, nextProtein, atom, *molecule are all OK


Preprocessor statements

Constants and/or macros should not be defined in preprocessor (#define statements). That is, the following statement type should be avoided:

#define REAL float

Instead, the keyword typedef should be employed. Thus, the above example may be correctly written as:

	typedef	float REAL;


Classes

Every class should have a constructor, a destructor and a copy constructor defined by the programmer. For example, here are three constructors for the Atom class:

        Atom()                          // constructor for new atom
        virtual ~Atom(void) {}          // destructor
        Atom(const &Atom old_atom);     // copy constructor

Note the use of the keyword virtual. This instructs C++ to call the destructor of the derived class and then [if required] that of the base class.

Class data members should be explicitly declared to be private by using the private keyword:

class Atom
{
private:
        REAL            x,y,z;                  // separate coords
        vector          xyz;                    // coords as vector
        string          symbol;                 // atomic symbol
...
rest_of_code
....
};

The default mode of access protection is private, however, stating this explicitly in the code removes one further source of potential confusion.


Methods and Functions

The keyword const can replace the older #define preprocessor directive. Within classes, parameters declared as constants are not initialised upon declaration, rather, they are initialised by the constructor. Parameters which are to remain as constants and methods which will not alter class members should be declared as const to avoid confusion. For example, in the Atom class each Atom will have a certain atomic mass. In the base class we thus define:

...
        static const float atomicMass;
...

The parameter will be initialised within some derived class. Note that the additional parameter static acts to limit the scope of the variable to the class.


Booleans and Strings

The ANSI C++ standard now defines a new type (bool) which may be either true or false.

        bool flag = false;

The Standard Library defines the string type which should be used rather than the older char type.So, for example:

        char    symbol[3];

becomes:

        string  symbol;

This allows for more flexible string handling.


Casting

This will occur by default in C++, as long as older style casts are avoided.

Thus, C-style casting such as:

        float angle;
        (double)angle = sin(45);        // forces angle to be treated
                                        // as a double

should not be employed at all !


Libraries

The C++ header file iostream.h declares the basic C++ streams (I/O) routines which allow the use of C++ input/output facilities (such as cout or cin). These should be used in preference over C style I/O facilities.



Go Back to the Software Engineering Home Page Any questions and bug reports to Mark Williams. This page was last updated on 19th June 2005