Rule 21 No member functions are to be defined within the class definition.
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.
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. This rule will be in effect at least as long as traditional text editors are used.
A similar problem is that members are private if no access specifier is explicitly given. This problem is avoided by following Rule 20.
Exception to Rule 20: No exceptions.
Exception to Rule 21: No exceptions.
class String : private Object { public: String(); // Default constructor String( const String& s ); // Copy constructor unsigned length() const; // ... protected: int checkIndex( unsigned index ) const; // ... private: unsigned noOfChars; // ... };
// Instead of writing like this: class String { public: int length() const // No !! { return len; } // ... private: int len; }; // Do it this way: class String { public: int length() const; // ... private: int len; }; inline int String::length() const { return len; }
Rec. 21 When declaring functions, the leading parenthesis and the first argument (if any) are to be written on the same line as the function name. If space permits, other arguments and the closing parenthesis may also be written on the same line as he function name. Otherwise, each additional argument is to be written on a separate line (with the closing parenthesis directly after the last argument).
Rec. 22 In a function definition, the return type of the function should be written on a separate line directly above the function name.
Rec. 23 Always write the left parenthesis directly after a function name.
If no return type is explicitly provided for a function, it is, by default, an int. It is recommended to always provide the return type explicitly, to increase the readability of the code. By defining the return type on a separate line directly above the function definition, the function name is more easily seen.
The other recommendations are meant to give a uniform appearance to the code that is written. Until such time as formatting tools are available, programmers should follow these guidelines.
void foo (); // No!! void foo(); // Better
// Right: int myComplicatedFunction( unsigned unsignedValue, int intValue, char* charPointerValue, int* intPointerValue, myClass* myClassPointerValue, unsigned* unsignedPointerValue ); // Wrong: int myComplicatedFunction( unsigned unsignedValue, int intValue, char* charPointerValue, int* intPointerValue, myClass* myClassPointerValue, unsigned* unsignedPointerValue );
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 the style which, in our opinion, gives the most readable code. Other styles may well provide more compact code.
At times, everything that is to be 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. 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.
// No block at all - No! while ( /* Something */ ); // Empty block - better! while ( /* Something */ ) { // Empty ! }
The characters `*' and `&' should be written together with the types of variables instead of with the names of variables in order to emphasize that they are part of the type definition. Instead of saying that *i is an int, say that i is an int*.
Traditionally, C recommendations indicate that `*' should be written together with the variable name, since this reduces the probability of making a mistake when declaring several variables in the same declaration statement (the operator `*' only applies to the variable on which it operates). Since the declaration of several variables in the same statement is not recommended, however, such a advice is unneeded.
char* Object::asString() { // Something }; char* userName = 0; int sfBook = 42; int& anIntRef = sfBook;
// NOT RECOMMENDED char* i,j; // i is declared pointer to char, // while j is declared char
Rec. 28 Use the c++ mode in GNU Emacs to format code.
In our opinion, code is more readable if spaces are not used around the . or -> operators. The same applies to unary operators (those that operate on one operand), since a space may give the impression that the unary operand is actually a binary operator.
Ordinary spaces should be used instead of tabs. Since different editors treat tab characters differently, the work in perfecting a layout may have been wasted if another editor is later used. Tab characters can be removed using the UNIX command expand. One alternative is to format code using the editor GNU Emacs.
We recommend that everyone use GNU Emacs to format code. Code will then have a uniform appearance regardless of who has written it.
Next section: 7 Style