All names should be descriptive unless they are better left as a single letter or word. Words in names should be separated by underscores, except for class names and enum keywords. In class names and enum keywords the first letter in each word should be capitalized and underscores should be avoided. Private member variables should end with an underscore. Functions, variables and enum tags should preferably be all in lower-case. Global variables should be prefixed with upper-case GLOBAL_ and static variables (but not static member variables) with upper-case STATIC_.
class MyClass { public: enum State { active, inactive }; double calculate_number(void) const; private: double value_; }; double MyClass::calculate_number(void) const { extern int GLOBAL_factor; return value_*GLOBAL_factor; }
#ifndef symbol #define symbol <the complete body of the header file> #endifNote, no lines of code or comments should be outside the #ifndef ... #endif construct. This allows compilers to optimize the reading of header files.
The symbol used in the conditional compilation statement should be made up from the project name and module name. If the module name is MyClass.h and the module is in project myproject then the symbol name should be _theplu_myproject_myclass_. The idea of this symbol is that it should be unique in the environment where it is used.
The multiple-inclusion protection should be followed by #include statements that describe which interfaces the module depends on. Typically a module depends only on the interfaces of base classes, classes that are contained by value or classes whose member functions are called within inline functions.
Next comes the forward declarations of the classes that the module uses and contains. Forward declarations should always be preferred to #include statements, which only should be used when necessary. This will minimize code dependencies, and make the programmer more conscious about what is used and what is not used in their code.
The #include statements and forward declarations should both be structured in blocks (separated by empty lines). Each block should contain modules of similar origin and each block should be sorted alphabetically. If needed, a block should begin with a comment explaining it.
All header files must include config.h first (if it's needed), followed by the primary header. So for example, File.cc should include its primary header File.h first (config.h omitted here), before other header files. This guarantees that the completeness of each header file is tested during compilation. After the primary header follows inclusion of header files located in the same directory followed by header files belonging to the same project but located in other directories. Then 3rd party project header files are included and last standard header files are included.
#include "config.h" #include "File.h" // Classes from this project #include "OtherClass.h" #include "path/to/other/dir/in/project/SomeClass.h" // Classes from project X #include <MyOtherProjectClass.h> #include <iostream> #include <vector>
Next comes the class specifications, followed by additional operators such as operator and finally comes the implementation of inline member functions if these are not defined already in the class declaration. We do not support the idea of collecting all inline functions in a separate file since this will only give another file to keep track of.
class MyClass { public: double public_function(void); protected: int protected_function(void); private: string name_; };The member functions should in each section start off with the constructors, followed by the destructors, then follows the member functions in alphabetical order, and finally the operators are declared in the order defined in Appendix B.
/** Some text documenting the class MyClass */ class MyClass
Try to keep comment line lengths within the terminal character limit, i.e less than 80 characters per line. This will make the comments more readable.
We begin the implementation file with the necessary #include statements and we structure them in the same way as in the header files (see Section 2.2) with the exception that the class's own header file must be included first.
Next comes the definition of member functions and they are ordered in the same way as a section in the class declaration. At the end we have the definitions of additional operators such as operator.
In general we use the
if (mycondition) { // statements inside the if }everywhere where braces are used. The exceptions are brace usage in function definitions
MyClass::public_function(void) { // function body }and in inline declarations we prefer a more compact style
class MyClass { public: inline double return_zero(void) { return 0; } inline double another_public_function_with_a_long_name(void) { return some_function_returning_double(); } }where the second style is used when the line has to be split for readability. If declaration and definition for inline functions are separated then the function definition style is preferred.