Development guide

Styles

Classes

The public, protected, and private sections of a class are declared in that order (the public section is declared before the protected section which is declared before the private section).

By placing the public section first, everything that is of interest to a user is gathered in the beginning of the class definition. The protected section may be of interest to designers when considering inheriting from the class. The private section contains details that should have the least general interest.

With the exception of templates where current compiler technology commands it, member functions are never defined within the class definition.

Functions

Inline functions are defined in a separate block following the class declaration.

A member function that is defined within a class definition automatically becomes inline. Class definitions are less compact and more difficult to read when they include definitions of member functions. It is easier for an inline member function to become an ordinary member function if the definition of the inline function is placed outside of the class definition.

When declaring functions, the leading parenthesis and the first argument (if any) are written on the same line as the function name. If space and readability permit, other arguments and the closing parenthesis may also be written on the same line as the function name. Otherwise, each additional argument is written on a separate line, indented with four spaces (with the closing parenthesis directly after the last argument).
// Long function declarations:
DateTime &assign(int year,
    int month,
    int day,
    int hour = 0,
    int minute = 0,
    int second = 0,
    int millisecond = 0,
    int microseconds = 0);
Always write the left parenthesis directly after a function name. There is no space between the function name, the opening brace and the first argument declaration. Also there is no space between the last argument and the closing parenthesis.

Templates

The template keyword, together with the template argument list, is written on a separate line before the following class or function definition.

Compound statements

Braces ("{}") enclosing a block are placed in the same column, on separate lines directly before and after the block.

The placement of braces seems to have been the subject of the greatest debate concerning the appearance of both C and C++ code. We recommend a style that, in our opinion, gives the most readable code. Other styles may well provide more compact code.

Flow control statements

There is always a space between the flow control statement’s keyword and the opening parenthesis of the control expression. There is no space between the opening parenthesis and the expression. There is also no space between the expression and the closing parenthesis.
The flow control primitives if, else, while, for and do should be followed by a block, even if it is an empty block, or consisting of only one statement.

At times, everything that is done in a loop may be easily written on one line in the loop statement itself. It may then be tempting to conclude the statement with a semicolon at the end of the line. This may lead to misunderstanding since, when reading the code, it is easy to miss such a semicolon. Also, the semicolon could be deleted by accident, leading to a hard-to-find bug. It seems to be better, in such cases, to place an empty block after the statement to make completely clear what the code is doing. Even more better is to avoid this style altogether. In certain cases, a code that is more compact might be better readable than code with many blocks containing only a single statement. As a general rule, readability must always be preferred to strict style adherence.

// Blocks and single statements:
int ASCIIEncoding::convert(int ch, unsigned char *bytes, int length) const
{
    if (ch >= 0 && ch <= 127)
    {
        *bytes = (unsigned char) ch;
        return 1;
    }
    else 
        return 0;
}
// Single-line flow control statements can improve readability by keeping the code more compact:
void MessageHeader::splitParameters(const std::string &s,
    std::string& value,
    NameValueCollection& parameters)
{
    value.clear();
    parameters.clear();
    std::string::const_iterator it = s.begin();
    std::string::const_iterator end = s.end();

    while (it != end && isspace(*it)) ++it;
    while (it != end && *it != ';') value += *it++;

    trimRightInPlace(value);
    if (it != end) 
        ++it;
    
    splitParameters(it, end, parameters);
}

Pointers and references

The dereference operator "*" and the address-of operator "&" should be directly connected with the variable names in declarations and definitions.

Miscellaneous

Never declare more than one variable in a single statement.
Do not use spaces around "." or "->", nor between unary operators and operands.
Indentation is done with spaces. Each indentation level corresponds to four spaces. Tab characters may not be used for indentation.