The C++ coding standards were developed to insure consistency throughout our C++ source code. It is the intention of these standards to provide necessary source code consistency, while not being overly restrictive. The standards are conveyed as a set of general rules and source code examples. The standards, as supplied, do not comprise a definitive list. They do however, provide general guidelines to coding style.
###Standard File Header
All C++ source files shall contain the following comment at the top of the file:
// Instrumentation Laboratory
// Copyright (C) 2002. All Rights Reserved.
Header files should always be bracketed by #ifdef, #define, and #endif to ensure that if they are never included more than once.
// Above header comment
# ifndef **_HPP
# define **_HPP
Typically, header files (either .h or .hpp) contain the interface spec for a piece of functionality, whether it is a class, a collection of functions, or a set of global variable extern declarations. The purpose of this file is to describe to the user of this functionality how to use it.
Each class should have a descriptive comment describing what the class is used for. Each function/member function should have a comment describing its functionality and its interface.
Publicly accessible functionality (whether global functions, public member functions or protected member functions) requires the most complete descriptions in the header file. Private, implementation oriented comments should be put in the implementation file (typically a .c or .cpp file).
Strategic comments are used to describe the intended functionality of a block of code, not to describe what the code does (see below). These are meant to help a code maintainer understand the purpose of the code, not the implementation details.
Tactical comments describe what individual pieces of code do. They are especially useful in complicated pieces of code. These are meant to help a code maintainer understand the implementation details of the code.
The purpose of coding conventions is the make code from different developers have a similar appearance making it easier to understand the code. It is not intended to make the code look perfect, as there is no such thing.
* Never use tabs in code. Always use spaces.
* Standard indentation level is 3 spaces
* All control structures shall be indented on level deeper than the level containing them.
* All braces should be on lines by themselves indented to the same level as the block that contains them.
* Complex expressions should be fully parenthesized.
* Line breaks in complex expressions should be before an operator
* Class member names (either functions or variables) should begin with “m_”
* Global variable names should begin with “g_”
* The first letter of the name of a variable of a simple type (not including the above prefix) should be a letter indicating the basic type:
**** “i” for integer types
**** “f” for floating point types
**** “b” for Boolean
**** “e” for enumeration
**** “c” for character
####Prefer Includes in .cpp files
The more that header files include other header files, the more dependencies are created that are not needed. As much as possible, header files should only include other header files that are necessary for the interface being defined.
The #define provides no type safety and no scoping.
* Prefer inline functions to macros
* Prefer static const to defined constants
* Prefer enumerations
* Prefer templates
* Use #define only for conditional compilation
Variables should be scoped as tightly as possible. The rationale is that it is trivial to increase the scope of a variable if needed, but reducing the scope can be next to impossible (i.e. the genie is out of the bottle).
####Use const as much as possible
Similar to scoping, taking away constness is trivial, but adding it later is next to impossible. This is especially important with the use of reference variables.
####Prefer exceptions to assert
Assert is non-recoverable. On failure it exits the process. Therefore:
* If the assert is not encountered during testing, the only thing that is known is that the error condition didn’t happen during testing. We don’t know if it will never happen.
* Since we don’t know that it will never happen, we need to write code to properly recover from that error condition.
* Therefore, throw a c++ exception rather than using an assert.
####Always provide a bool expression in control statements
The fact that any non-zero expression results in a true value in control statements should not be depended on.
####When comparing a variable against a constant, the constant shall be to the left of the comparison operator.
This helps ensure that the variable isn’t accidentally assigned to during the comparison by leaving out one of the ‘=’.
####All subsystems should be enclosed in namespaces of the same name.
By enclosing subsystems in namespaces, the use of third party products is easier since the chance of name clashes is greatly reduced.
####Prefer dynamic*cast and static*cast to C-style Casting
C++ provides type-safe casting as part of the language. A c-style cast breaks type safety and makes it more difficult to write robust code
####Prefer descriptive variable names to short names
The more descriptive a variable name is, the easier maintenance is later. This does not mean that variable names should be made artificially long, but rather however long they end up being they should be very descriptive of their intended use.
STL (The Standard Template Library) is a collection of proven C++ classes that provide functionality for many common programming techniques, for instance stacks, queues, maps, vectors, etc. These are well debugged, well documented classes and should be used instead of re-implementing their functionality.
A good reference for STL can be found at: http://www.cppreference.com/cpp_stl.html
Class Specific Coding Rules
* All classes shall be declared in header files of the same base name
* All classes shall be implemented in source files of the same base name
* Always provide an initialization for every member variable in a constructor
* The C++ language specification specifies that the order of construction of member variables is in the order they are declared, not in the order specified in the constructor. Therefore, in order to avoid invalid implications, the order that the member variables are listed in the constructors should be in the order declared in the class. This is a visual reminder as to the actual construction order which is always the order declared in the class.
* Construct each member on a line by itself. This makes it easier to find.
* Always call a constructor for a base class.
* Avoid multiple inheritance.
* Avoid the use of friends as much as possible. It breaks encapsulation.
The purpose of a class definition is two-fold
* The first is to tell the compiler information about the class
* The second, and more important from a developers perspective, is to tell a user of the class everything needed in order to use the class. In this sense, it is to be considered a document which describes the usage of the class.
Given that, the class should be organized with this in mind.
* The entire public interface should be defined first. This is the code that any usage of the class requires
* The protected interface is second. This is the code that a derived class implementation needs to understand
* The private interface is third. This is only relevant to the implementation of the class.
In order to preserve as much encapsulation as possible, the scoping in classes should be as tight as possible.
* Every member (either function or variable) should be private unless it is needed by derived classes or public users.
* If not private, every member should be protected, unless it is needed by a public user
* Anything needed by a public user.
###Constructors and Destructors
####Always declare default constructors and assignment operators
C++ provides default implementations for the default construct, the copy constructor, and the assignment operator if not declared in the class specification. These default implementations are wrong most of the time. By providing at least a declaration of these, it prevents the automatic creation of them by the compiler.
If the class has no use for any of these, the declarations should still be made in the private interface, and no implementation needs to be provided. This will catch at compile time any external reference to these, and at link time any reference in the class.
####All destructors should be virtual