C++

Objectives :

  • Rules Recommendation :  Industrial Strength C++

Step: 1 Create a project

Rules and recommendations

Naming

Meaningful names

Rec 1.1 Use meaningful names.

Rec 1.2 Use English names for identifiers.

Rec 1.3 Be consistent when naming functions, types, variables and constants.

Names that collide

Rec 1.4 Only namespace names should be global.

Rec 1.5 Do not use global using declarations and using directives inside header

files.

Rec 1.6 Prefixes should be used to group macros.

Rec 1.7 Group related files by using a common prefix in the file name.

Illegal naming

Rule 1.8 Do not use identifiers that contain two or more underscores in a row.

Rule 1.9 Do not use identifiers that begin with an underscore.

Organizing the code

Rule 2.1 Each header file should be self-contained.

Rule 2.2 Avoid unnecessary inclusion.

Rule 2.3 Enclose all code in header files within include guards.

Rec 2.4 Definitions for inline member functions should be placed in a separate file.

Rec 2.5 Definitions for all template functions of a class should be placed in a separate file.

Comments

Rec 3.1 Each file should contain a copyright comment.

Rec 3.2 Each file should contain a comment with a short description of the file content.

Rec 3.3 Every file should declare a local constant string that identifies the file.

Rec 3.4 Use // for comments.

Rec 3.5 All comments should be written in English.

Control flow

Rule 4.1 Do not change a loop variable inside a for-loop block.

Rec 4.2 Update loop variables close to where the loop-condition is specified.

Rec 4.3 All flow control primitives (if, else, while, for, do, switch

and case) should be followed by a block, even if it is empty.

Rec 4.4 Statements following a case label should be terminated by a statement that

exits the switch statement.

Rec 4.5 All switch statements should have a default clause.

Rule 4.6 Use break and continue instead of goto.

Rec 4.7 Do not have too complex functions.

Object Life Cycle

Initialization of variables and constants

Rec 5.1 Declare and initialize variables close to where they are used.

Rec 5.2 If possible, initialize variables at the point of declaration.

Rec 5.3 Declare each variable in a separate declaration statement.

Rec 5.4 Literals should only be used in the definition of constants and enumerations.

Constructor initializer lists

Rec 5.5 Initialize all data members.

Rule 5.6 Let the order in the initializer list be the same as the order of declaration in

the header file. First base classes, then data members.

Rec 5.7 Do not use or pass this in constructor initializer lists.

Copying of objects

Rec 5.8 Avoid unnecessary copying of objects that are costly to copy.

Rule 5.9 A function must never return, or in any other way give access to, references

or pointers to local variables outside the scope in which they are declared.

Rec 5.10 If objects of a class should never be copied, then the copy constructor and

the copy assignment operator should be declared private and not implemented.

Rec 5.11 A class that manages resources should declare a copy constructor, a copy assignment

operator, and a destructor.

Rule 5.12 Copy assignment operators should be protected from doing destructive actions

if an object is assigned to itself.

Conversions

Rec 6.1 Prefer explicit to implicit type conversions.

Rec 6.2 Use the new cast operators (dynamic_cast, const_cast,

reinterpret_cast and static_cast) instead of the old-style casts,

unless portability is an issue.

Rec 6.3 Do not cast away const.

Rule 6.4 Declare a data member as mutable if it must be modified by a const member

function.

The class interface

Inline functions

Rec 7.1 Make simple functions inline.

Rule 7.2 Do not declare virtual member functions as inline.

Argument passing and return values

Rec 7.3 Pass arguments of built-in types by value, unless the function should modify

them.

Rec 7.4 Only use a parameter of pointer type if the function stores the address, or

passes it to a function that does.

Rec 7.5 Pass arguments of class types by reference or pointer.

Rule 7.6 Pass arguments of class types by reference or pointer, if the class is meant

as a public base class.

Rule 7.7 The copy assignment operator should return a non-const reference to the object

assigned to.

Const Correctness

Rule 7.8 A pointer or reference parameter should be declared const if the function

does not change the object bound to it.

Rule 7.9 The copy constructor and copy assignment operator should always have a

const reference as parameter.

Rule 7.10 Only use const char-pointers to access string literals.

Rule 7.11 A member function that does not change the state of the program should be

declared const.

Rule 7.12 A member function that gives non-const access to the representation of an

object must not be declared const.

Rec 7.13 Do not let const member functions change the state of the program.

Overloading and default arguments

Rule 7.14 All variants of an overloaded member function should be used for the same

purpose and have similar behavior.

Rec 7.15 If you overload one out of a closely-related set of operators, then you should

overload the whole set and preserve the same invariants that exist for builtin

types.

Rule 7.16 If, in a derived class, you need to override one out of a set of the base class'

overloaded virtual member functions, then you should override the whole

set, or use using-declarations to bring all of the functions in the base class

into the scope of the derived class.

Rule 7.17 Supply default arguments with the function's declaration in the header file,

not with the function's definition in the implementation file.

Conversion functions

Rec 7.18 One-argument constructors should be declared explicit.

Rec 7.19 Do not use conversion functions.

new and delete

Rule 8.1 delete should only be used with new.

Rule 8.2 delete [] should only be used with new [].

Rule 8.3 Do not access a pointer or reference to a deleted object.

Rec 8.4 Do not delete this.

Rec 8.5 If you overload operator new for a class, you should have a corresponding

overloaded operator delete.

Rec 8.6 Customize the memory management for a class if memory management is

an unacceptably-large part of the allocation and deallocation of free store

objects of that class.

Static Objects

Rec 9.1 Objects with static storage duration should only be declared within the scope

of a class, function or anonymous namespace.

Rec 9.2 Document how static objects are initialized.

211

Object-oriented programming

Encapsulation

Rule 10.1 Only declare data members private.

Rec 10.2 If a member function returns a pointer or reference, then you should document

how it should be used and for how long it is valid.

Dynamic binding

Rec 10.3 Selection statements (if and switch) should be used when the flow of

control depends on an object's value, while dynamic binding should be used

when the flow of control depends on the object's type.

Inheritance

Rule 10.4 A public base class must either have a public virtual destructor or a protected

destructor.

Rule 10.5 If you derive from more than one base classes with the same parent, then that

parent should be a virtual base class.

The Class Interface

Rec 10.6 Specify classes using preconditions, postconditions, exceptions and class invariants.

Rec 10.7 Use C++ to describe preconditions, postconditions and class invariants.

Rule 10.8 A pointer or reference to an object of a derived class should be possible to

use wherever a pointer or reference to a public base class object is used.

Rec 10.9 Document the interface of template arguments.

Assertions

Rule 11.1 Do not let assertions change the state of the program.

Rec 11.2 Remove all assertions from production code.

Error handling

Different ways to report errors

Rec 12.1 Check for all errors reported from functions.

Rec 12.2 Use exception handling instead of status values and error codes.

When to throw exceptions

Rec 12.3 Only throw exceptions when a function fails to perform what it is expected

to do.

Rec 12.4 Do not throw exceptions as a way of reporting uncommon values from a

function.

Rule 12.5 Do not let destructors called during stack unwinding throw exceptions.

212 Industrial Strength C++

Rec 12.6 Constructors of types thrown as exceptions should not themselves throw exceptions.

Exception-safe code

Rec 12.7 Use objects to manage resources.

Rule 12.8 A resource managed by an object must be released by the object's destructor.

Rec 12.9 Use stack objects instead of free store objects.

Rec 12.10 Before letting any exceptions propagate out of a member function, make

certain that the class invariant holds, and if possible leave the state of the object

unchanged.

Exception types

Rec 12.11 Only throw objects of class type.

Rec 12.12 Group related exception types by using inheritance.

Rec 12.13 Only catch objects by reference.

Error recovery

Rule 12.14 Always catch exceptions the user is not supposed to know about.

Rec 12.15 Do not catch exceptions you are not supposed to know about.

Exception specifications

Rec 12.16 Use exception specifications to declare which exceptions that might be

thrown from a function.

Parts of C++ to avoid

Library functions to avoid

Rec 13.1 Use new and delete instead of malloc, calloc, realloc and free.

Rule 13.2 Use the iostream library instead of C-style I/O.

Rule 13.3 Do not use setjmp() and longjmp().

Rec 13.4 Use overloaded functions and chained function calls instead of functions

with an unspecified number of arguments.

Language constructs to avoid

Rule 13.5 Do not use macros instead of constants, enums, functions or type definitions.

Rec 13.6 Use an array class instead of built-in arrays.

Rec 13.7 Do not use unions.

Size of executables

Rec 14.1 Avoid duplicated code and data.

Rule 14.2 When a public base class has a virtual destructor, each derived class should

213

declare and implement a destructor.

Portability

General aspects of portability

Rule 15.1 Do not depend on undefined, unspecified or implementation-defined parts

of the language.

Rule 15.2 Do not depend on extensions to the language or to the standard library.

Rec 15.3 Make non-portable code easy to find and replace.

Including files

Rule 15.4 Headers supplied by the implementation should go in <> brackets; all other

headers should go in "" quotes.

Rec 15.5 Do not specify absolute directory names in include directives.

Rec 15.6 Include file names should always be treated as case sensitive.

The size and layout of objects

Rule 15.7 Do not make assumptions about the size of or layout in memory of an object.

Rule 15.8 Do not cast a pointer to a shorter quantity to a pointer to a longer quantity.

Rec 15.9 If possible, use plain int to store, pass or return integer values.

Rec 15.10 Do not explicitly declare integral types as signed or unsigned.

Rule 15.11 Make sure all conversions of a value of one type to another of a narrower

type do not slice off significant data.

Rec 15.12 Use typedefs or classes to hide the representation of application-specific

data types.

Unsupported language features

Rec 15.13 Always prefix global names (such as externally visible classes, functions,

variables, constants, typedefs and enums) if namespace is not supported by

the compiler.

Rec 15.14 Use macros to prevent usage of unsupported keywords.

Rec 15.15 Do not reuse variables declared inside a for-loop.

Other compiler differences

Rec 15.16 Only inclusion of the header file should be needed when using a template.

Rec 15.17 Do not rely on partial instantiation of templates.

Rec 15.18 Do not rely on the lifetime of temporaries.

Rec 15.19 Do not use pragmas.

Rule 15.20 Always return a value from main().

Rec 15.21 Do not depend on the order of evaluation of arguments to a function.

214 Industrial Strength C