// This file describes the coding guidelines for c++.
// It file is best viewed by browsing the doxygen-generated documentation.
// It appears under the the "Related Pages" tab.
// Consult the README file for instructions on generating the documentation.
/*! \page CppCodingGuidelines C++ Coding Guidelines
The following guidelines are based on a draft document from Baudouin Raoult.
\section files_extensions Files Extensions
- Each class is defined in two files, the header file, that contains the class
definition, with an extension of .h, and the implementation file
with the extension .cc
- The file names should match the name of the class.
- .cc and .h files must be in the same directory.
- A .h file should not include more than one class definition,
except in the case of a factory class, which may be defined in the same file
as the class it manufactures.
\section header_files Header Files
- Header files should follow the layout suggested in
\link ExampleHeader Documents/ExampleHeader.h\endlink.
- The public, protected and private sections
of a class should be declared in that order (i.e. public first,
private last).
- Use \#include guards to protect against multiple inclusions.
- Header files should not contain namespace using statements, since
this causes the namespace to be "used" in any file that includes the header.
\section code_documentation Code Documentation
- Documentation is generated using doxygen.
- Instructions on building the documentation are in the
\link README README\endlink file.
- The doxygen manual can be found
here.
- See here
for instructions on including \f$\mbox{\LaTeX}\f$ mathematical formulae.
- Doxygen recognises special comments:
- A brief comment is a single line like this:
\verbatim //! This one-line comment gives a brief description of a class or method.\endverbatim
- A detailed comment looks like this:
\verbatim /*!
* This is a detailed comment. It has more than one line,
* and provides more complete information about a class or method.
*/ \endverbatim
- Class definitions should be preceded by a doxygen brief comment
followed by a detailed comment.
- Methods declarations and members should be preceded by a doxygen brief
comment, unless the role of the method or member is completely obvious from
its name. A detailed comment may also be provided.
- Normal C++ comments should be used in .cc files where necessary to
explain the internal logic of a function.
- Don't include comments to indicate authorship or modification history.
That is what git blame is for!
- HTML links to auxilliary documents (e.g. pdf files) can be made to appear on
the \link Overview Overview\endlink page by adding them to
Documents/overview.h
\section includes Includes
Don't include unessesary headers. Use class forwarding. The compiler only
needs to see a class definition when calling methods or establishing the size
of an object. When refering to a pointer or a reference, the compiler does not
need to know the detail of the class.
\section identifiers Identifiers
- Identifiers should be in lower case with an upper case letter
at the start of each internal word: e.g. changeResolution
- Class names should start with an upper case letter
- Method and member names should start with a lower case letter
- Member names have an underscore at the end
- All other variables should be all lower case
- Use short identifiers for local variables, loop indices, etc.
- Use longer, meaningful names for methods, members, classes, etc.
\section use_of_const Use of Const
- Use const wherever possible.
- Avoid passing objects by const value. Pass by const reference instead.
- Remember. The rule when reading definitions is to work from right
to left. So, for example, char * const test means that
test is a const pointer to a char object:
- const char * test = "xyz"; // non-const pointer to const data
- char * const test = "xyz"; // const pointer to non-const data
- const char * const test = "xyz"; // const pointer to const data
- bool isEmpty() const; // the isEmpty method does not change its object.
\section constructors_and_destructors Constructors and Destructors
- Always declare copy and assignment constructors. Make them private unless
you need to copy.
- If the default copy constructor is sufficient, include a comment to this
effect in the class definition.
- Write the constructors and the destuctors at the same time.
- If the class has a virtual table, its destructor must be virtual.
- All resources allocated by an object must be deallocated in the destuctor.
- Beware of partially constructed objects.
- Except for the copy constructor, single-argument constructors should be
declared explicit to prohibit implicit type conversions.
- If you need copy, assignment or a destructor, then you probably need
all three.
- Base class destructors must be either public and virtual,
or protected and not virtual.
- The copy constructor should copy all the data. However, you may wish to give it a second,
default argument to allow this behaviour to be over-ridden.
- Note that MyClass a = b calls the copy constructor, not the
assignment operator.
\section members Member Variables
- Member variables should always be private.
- Use accessors if you need to access a member variable from outside a class.
- Don't use the accessors from within the class. Use the member itself.
\section accessors Accessors
Accessors are short methods designed to access members.
- Accessors should only be implemented if necessary (they break the encapsulation)
- Accessors should be inline
- Accessors must have the same name as the member (but without the underscore)
\section Methods
- A method is a request to an object to do something or to provide something.
The name of the method should reflect this.
- E.g. changeResolution is preferable to resolutionChanger.
\section pointers Pointers and References
- Prefer references to pointers. If an object is guaranteed to exist, use a
reference.
- Passing or returning an non-const pointer means passing ownership of the
pointed object.
- Passing or returning a const pointer means keeping ownership of the pointed
object, and that the pointed object can be null
- In any other case, pass a referece to the object. Use const whenever the
object will not be modified.
\section c_code C Code
- Don't use C functions (e.g. printf) if C++ provides the same
functionality.
- Avoid using C style casts.
- For unsigned value, use a typedef: typedef unsigned long ulong;
\section preprocessor Preprocessor
- The preprocessor should only be used to define \#include guards in
.h files and for variables specified via the -D flag at
compile time.
- The preprocessor should not be used to define macros or constants.
\section namespaces Namespaces
- Model-independent code should be defined in the oops namespace.
- Model-specific code should be defined outside the the oops
namespace.
- Do not use an entire namespace. In particular, do not use the
statement: using namespace std;
- Explicitly list the things you are using from other namespaces:
- using std::cout;
- using oops::Model;
- etc.
- using statements must never be used at global scope in a header file.
- Use anonymous namespaces to restrict classes (e.g. Factories) to file scope.
\section readability Readability
- Indent class and function bodies, if and for blocks, etc.
- The opening brace should appear
- either: on the same line as the argument list, initialisation list,
loop expression. etc.
- or: on its own line, aligned with the start of the statement
- The closing brace should appear on its own line, and aligned with
the start of the statement it closes.
- Keep lines below 80 characters.
- Split long lines in a way that makes it obvious that the code continues
on the next line.
- Continuation lines should be indented.
- If you split an argument list, align the arguments with those on
the previous line.
\section optimization Optimization
- Pass objects by reference, not by value.
- Prefer initialization over assignment.
- Use ++i, not i++ when incrementing iterators.
- Use the initialization list to initialize member objects.
\section miscellaneous Miscellaneous
- Make interfaces non-virtual.
- Make virtual functions private.
- Check for assignment to self in operator=.
*/