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.
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.
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.
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 should have the extension .h as final suffix.
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.
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).
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 |
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;
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.
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.
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.
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 !
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.
Any questions and bug reports to
Mark Williams.
This page was last updated on 19th June 2005