# Coding conventions

The coding conventions are organized under various headings, and each rule is tagged according to how it affects the program code.

viability - the code will not work unless you follow this rule.

reliability - the code may not work unless you follow this rule.

maintainability - the code may be difficult to modify unless you follow this rule.

readability - the code may be difficult to understand unless you follow this rule.

reusability - the code may be less usable in conjunction with other code unless you follow this rule.

convention - the code will be unconventional unless you follow this rule.

The rules are also tagged according to whether they are:

C++ - general 'good practice' C++ coding rules.

Symbian - Symbian OS-specific rules.

S60 - S60 recommended rules.

Some entries are tagged as notes rather than rules.

### Contents

- assertions

- C classes

- class invariants

- classes

- coding style

- comments

- compilation errors

- constants

- construction

- constructors

- consts

- destruction

- destructors

- DLLs

- exceptions

- files

- flow control

- functions

- header files

- #include

- inheritance

- invariants

- local variables

- M classes

- macros

- member variables

- operators

- parameters

- pointers

- postconditions

- preconditions

- R classes

- resource files

- statements

- strings

- structs

- T classes

- TBool types

- templates

- types

- unions

- variables

- virtual functions

### A

assertions |  |
--- | --- | ---
reliability | Symbian | A function body can start with a list of `__ASSERT_ALWAYS()` macros that verify that the parameters are valid. These are to check that the function is being called correctly. In particular they check that run-time input is valid, and that the object to which the function is being applied is in a valid state. A precondition can be read as "This function is not guaranteed to work correctly unless <precondition expression> If the function isn't part of a public API consider using the macro `ASSERT_DEBUG()` instead. Points to remember: If you have a precondition that a pointer is not null, consider passing a reference instead of a pointer. If you have a precondition that a value passed in is in a valid range, consider passing an enumeration or a T-class object. Constructors may run precondition checks on their parameters. However, these parameters are used in the member initialisation list., so it is usually better to put the tests in the body of the constructor. Precondition assertions should be documented as comments against their corresponding function prototype in the header file. Any member function should cope with all situations not excluded by the preconditions expressed in the header. Preconditions should not be placed in `NewL()` or `NewLC()` but instead within the constructor and `ConstructL()` functions. However, they are in fact still preconditions of `NewL()` and `NewLC()` and as such should exist as comments in the header file.
reliability | Symbian | At the end of any function it can be useful to check that the value you are returning is valid, or that the function has performed the task it promised. This is behavioural self-testing. Use the macro `ASSERT()` to perform these tests. These are to catch programmer errors in the function containing the postcondition. A postcondition can be read as "When this function returns, <postcondition expression> is guaranteed to be true, provided that all the preconditions held when it was called". Points to remember If a function has multiple returns, remember to put post-conditions before every return! If you have a post-condition that the pointer you return is not null, consider returning a reference. Post-conditions should be documented as comments against their corresponding function prototype in the header file.
reliability | Symbian | All non-trivial classes should implement invariant checking. Invariants can be thought of as preconditions and post-conditions that apply to all member functions of a class. The macro `__DECLARE_TEST` is a function declaration which should be invoked in the header file within a Protected clause. You need to implement the member function `void __DbgTestInvariant() const`. The first line should be a call to `__DbgTestInvariant()` on your base class (if the function is defined), followed by `ASSERT_DEBUG()` calls that verify that your member data is in a valid state. Example:
    void CMyClass::__DbgTestInvariant() const
    {
    ASSERT_DEBUG(iPointer);
    ASSERT_DEBUG((iValue>=KMinValue) && (iValue>=kmaxvalue)); }
    </pre>
Every public non-static function calls `__TEST_INVARIANT` at the start and at the end (or only once if the function is a single line query). Put Invariants before preconditions and after post-conditions. The last line in `ConstructL()` is `__TEST_INVARIANT`. Points to remember: You cannot call functions in `__DbgTestInvariant()` that call `__TEST_INVARIANT` (it is best not to call any functions). If a function has multiple returns, remember to call `__TEST_INVARIANT` before every return! You may call static functions at any time, as static member functions can't check the Invariant, not having any state to verify.

### C

C classes |  |
--- | --- | ---
See also classes |
| Symbian (note) | C class objects cannot be passed or returned by value, but only through pointers or by reference.
| Symbian (note) | Passing C class objects by pointer implies either the transfer of ownership, or that the parameter is optional. To remove this ambiguity, consider overloading functions that have optional parameters.
| Symbian (note) | Returning C class objects by pointer implies either the transfer of ownership, or that the return value may be `NULL`. To remove this ambiguity, consider pushing the object on to the cleanup stack before you return it, and adding a trailing C to the function name.

class invariants |  |
--- | --- | ---
|  | See assertions

classes |  |
--- | --- | ---
viability | Symbian | Every class in Symbian OS must be one of 5 kinds. To indicate which kind a class is, the name must be prefixed by a capital C, T, M, S, or R.
reliability | Symbian | C classes must always have a destructor (which is virtual by virtue of CBase). If the destructor is empty, then use the helpful comment `//empty destructor`.
maintainability | C++ | Try to avoid using friend classes, as they break encapsulation. If you feel you need to use a friend class do the following: Example: Class B is a friend of Class A, in order that it can call the non-public member functions `f()`, `g()`, `h()`. We simply define an interface:
    Class MyInterface
    {
    friend class B;
    protected:
    virtual void f() = 0;
    virtual void g() = 0;
    virtual void h() = 0;
    };
and then derive Class A from MyInterface.
reusability | C++ | Declare all classes in header files. If you want to hide a class, make it nested.
convention | S60 | There should be one (or none) `.cpp` and one `.h` file per class (except for nested classes).
convention | Symbian (note) | Any class that is derived from `CBase` has a "C" prefix.
| Symbian (note) | An M class only has virtual methods, and no data. The methods can at most have only a trivial implementation.
| Symbian (note) | C class objects can be pushed onto the cleanup stack.
| Symbian (note) | C class objects must either be newed, or (in rare cases) be a member variable of another C class.
| Symbian (note) | C classes inherit a private assignment operator from `CBase`, so it is not necessary for you to define one.

coding style |  |
--- | --- | ---
readability |  | Keep all lines fairly short, and always break the line if it goes off the edge of the screen. When you break a line, break it in a sensible place (for example, after rather than before an operator) and indent the following lines.
readability | C++ | Use white space to group related lines of code together.
readability | C++ | Use parentheses to clarify ambiguous code.
convention | S60 | There should be no spaces around primary operators ( '.', '*', '->' ). no spaces between unary operators and their operands one space on each side of all other operators no space between function names or macros and their arguments one space between a keyword and its parenthesised arguments matching spaces with matching parentheses.
convention | S60 | There must be no more than 120 characters per line. Indents should be by exactly four spaces.
convention | S60 | Braces should be indented according to Symbian's standards.

comments |  |
--- | --- | ---
readability |  | Don't write comments that simply mirror the code. Try to make your code less obscure instead of papering over it with comments.
convention |  | Stylised comment blocks in the format described below should be inserted into header files to help with automatic document generation. The convention is generally that used by Together, JavaDoc and CcDoc. There should be a separate comment block for each class, operation, and member variable declared in the header file. A comment block starts with a '/**' and ends with a '*/'. Each line starts with an asterisk '*'. The basic format is:
    /**
    * <BriefDescription>
    * <MarkUpTag>
    * <MarkUpTag>
    ...
    * <MarkUpTag>
    */
Alternatively a shorter form can be used:
    /** <BriefDescription> */
The `<BriefDescription>` should be an informal, one-sentence description of the class, operation or member variable. The `<MarkUpTag>` entries start with an `@` sign and are the first things (after the optional leading asterisk) on the line. Example:
    /*
    * A Rectangle object, which can be moved and rotated.
    *
    * @invariants iLength > 0;
    *  iHeight > 0;
    */
    class TRectangle
    {
    public:
    /**
    * Constructor
    *
    * @semantics Construct a new rectangle
    *
    at position ( aX , aY ),
    * length aLength, height aHeight.
    * @stereotype  constructor
    * @preconditions aLength >= 0; aHeight >= 0;
    */
    TRectangle( TReal x, TReal y, TReal aLength, TReal aHeight);
    /**
    * Rotate operation
    *
    * @semantics Rotate this rectangle by aAngle degrees
    * about its centre
    * @stereotype modifier
    * @preconditions aAngle >= 0; aAngle <= 360;
    */ void rotate(TReal aAngle);
    /**
    * Absolute move operation
    *
    * @stereotype  modifier
    * @semantics Move this rectangle to position ( aX , aY ).
    */
    void move_to(float x, float y);
    //data
    private:
    /** The x position of this rectangle*/
    TReal iPosX;
    /** The y position of this rectangle*/
    TReal iPosY;
    /** The length of this rectangle*/
    TReal iLength;
    /** The height of this rectangle*/
    TReal iHeight;
    }
convention | S60 | Use // for permanent comments in `.cpp` file code.

compilation errors |  |
--- | --- | ---
reliability | C++ | You should have zero compiler errors, except for unavoidable warnings that are due to the libraries you are using. Ideally you should also have a minimum of Lint warnings. Fix any Lint warnings that are fixable unless blatantly foolish and counter-productive.

constants |  |
--- | --- | ---
See also consts |
convention |  | The name for a constant should be prefixed by a capital K.
convention |  | Constants should be implemented as either: enums scoped within a class (for example, `enum { KMagicNumber = 3 };` , that is to say, no type name, and all on one line), or class scoped static members (for example, `static const TReal KMagicNumber;`) which must then be defined once only in a .cpp file. Note that this only works for built-in types, and that TInt64 is not a built-in type.

construction |  |
--- | --- | ---
See also constructors, destructors |
| Symbian (note) | C-classes are the only classes that you can `new`, and this is almost always the only way they are constructed.
| Symbian (note) | All C-class member variables are nulled on creation.

constructors |  |
--- | --- | ---
See also construction, destruction, destructors |
viability | Symbian | `ConstructL()` should never be a virtual function, since a partially constructed object isn't a polymorphic entity.
reliability | Symbian | Constructors and `ConstructL()` in C classes must be protected (or private), and should be empty apart from a member initialisation list and `ASSERT` macros. This enforces correct two-phase construction of objects.
reliability | Symbian | You must always have a `NewLC()` in a C class, unless it's a nested class where you have a bit more leeway. The `NewL()` is optional, and should always be implemented in terms of the `NewLC()`. Both should always follow the standard pattern, and call `ConstructL()`. Non standard construction makes code unclear, and prone to cleanup stack errors.
reliability | Symbian | In the implementation of `ConstructL()`, you should always call `ConstructL()` on the base class first. In certain circumstances you cannot help but break this rule, for example when you need to read in parameters from a resource file. Always scope this call to the base class to make things clearer.
| Symbian (note) | For small C classes it is acceptable to have a public constructor to allow them to be member variables of other C classes. This is normally only done for classes without a `ConstructL()`, such as the Symbian OS array classes.
| Symbian (note) | `NewL()` and `NewLC()` in C classes should be static, usually public, functions.
| Symbian (note) | Copy constructors lose their "special status" in Symbian OS. Normally only classes with a destructor need copy constructors, and this means C-classes, but C-classes are only instantiated via `NewL()` and `NewLC()`. C-classes derive a private copy constructor from `CBase`, and since any you define are never public, they cannot be called implicitly.

consts |  |
--- | --- | ---
See also constants |
reliability | C++ | `Const` correctness should be applied throughout. Most functions that return a value should not change the object they are applied to. These are called queries, and can mostly be made `const`. One word of caution, however: the compiler enforces that `const` functions preserve the object's bitwise state, but leaves it up to you to ensure that the object's abstract state is unchanged. Example: If you have member variable that is a pointer to another object, then the compiler allows you to call `non-const` functions on that object from within a `const` function!
    Class WorstCaseScenario
    {

    public:
    WorstCaseScenario() : iThis(this)
    {
    }
    void ChangeTheWorld();
    TBool InnocentLookingFunction() const
    {
    iThis->ChangeTheWorld();
    }
    WorstCaseScenario* iThis;
    }

### D

destruction |  |
--- | --- | ---
See also construction, constructors, destructors |
| Symbian (note) | If an object is deleted twice, this is a fatal error. This will occur if a `Leave` occurs whilst an object is both on the cleanup stack and is to be deleted in some object's destructor.

destructors |  |
--- | --- | ---
See also construction, constructors, destruction |
reliability | C++ | In a destructor or function called from a destructor you cannot assume that the object is fully constructed, hence you must check the state of the object and cope with all situations. You must not throw any exceptions. Example:
    MyClass::~MyClass()
    {
    if(iObject) //might be NULL if constructor failed
    {
    iObject->Close();
    delete iObject;
    iObject = NULL;
    }
    delete iFred;   //delete NULL is allowed
    iFred = NULL;
    }

DLLs |  |
--- | --- | ---
viability | Symbian | You must not have any global non-constant data in a `DLL`. This includes static member variables. The only global data you may have is constant static built-in types, that is, ones with no constructor.

### E

exceptions |  |
--- | --- | ---
viability | Symbian | You cannot use C++ style exceptions.

### F

files |  |
--- | --- | ---
See also header files |
viability | Symbian | Place Control IDs, and defines in `.hrh` files.
readabillity | Symbian | In a resource file, always use comments! Resource file comments are written to describe the usage of the file so that localisation can be based on them.
convention |  | Naming of `.mmp` and `.rss` files: If there is one, name it after the project (for example `animation.mmp`). If there are more than one, name them after the subproject (for example `engine.mmp`).
convention |  | There should be one directory per `.mmp` file, called group, or `<subproject>`. This should contain `.mmp`, `.def` and `readme` files.
convention |  | Public header files should go in a subdirectory inc, or `<subproject>` inc.
convention |  | Documents should all go in a subdirectory docs, or `<subproject>` docs.
convention |  | All files associated with the `.aif` file should be placed in a subdirectory aif. (To avoid name clashes with the `.rss` file)
convention |  | Test files should go in a subdirectory tsrc or `<subproject>` tsrc.
convention |  | All other files should go in a subdirectory src, or `<subproject>` src.
convention | Symbian | In a resource file, use the same bracketing conventions you're using in your source files.

flow control |  |
--- | --- | ---
reliability | C++ | Switch statements should always have a default clause. If the default should never occur, the default clause should be an assertion to that effect. The only clauses that should follow through (that is, no break) are empty ones, for example:
    switch(value)
    {
    case 0:
    case 1:
    case 2:
    DoSomething();
    break;
    case 4:
    case 5:
    DoSomethingElse();
    break;
    default:
    ASSERT(EFalse);//cannot occur
    }
maintainability | C++ | Never use `goto`.
maintainability | C++ | Single line statements after a `for` or an `if` statement should be parenthesized, that is:
    if(wantToDoSomething)
    {
    DoSomething();
    }

functions |  |
--- | --- | ---
See also virtual functions |
maintainability | C++ | Do not use default parameters (though exceptions can be made for having one default parameter only). If you have a function with 'n' default parameters, replace it with 'n+' overloaded versions of that function. It is usual to discover that not all the overloads are needed some better choices of overload can be found some of the overloads can be renamed more appropriately Example:
    AddControl(Control& ctrl, ControlObserver* observer = 0);
Becomes:
    AddControl(Control& ctrl);
    AddControl(Control& ctrl, ControlObserver* observer);
Which can be improved further to become:
    AddControl(Control& ctrl);
    AddControl(Control& ctrl, ControlObserver& observer);
readability | C++ | Separate functions into either modifiers - `non-const` functions that don't return a value, or queries - functions that return a value, are usually `const`, and due to preconditions probably don't `Leave`.
readability | C++ | Keep function bodies small.
readability | Symbian | Never return an error code. Use the `Leave` mechanism instead.
convention | C++ | Function names should begin with a capital letter. Normally Modifiers are expected to do something, and hence the name is in the form of an order.
convention | S60 | Functions should be defined in the same order as in the header file.
convention | Symbian | All inline functions should be in an `.inl` file. During development don't use inline functions. When you need to optimise before releasing the code, cut and paste the functions to be inlined from the `.cpp` file to an inline file ("`.inl`") which is then included by the header. Remember to add the keyword inline to the functions.
readability | Symbian (note) | Function names that end in a "C" indicate that the function returns a pointer that has been pushed onto the cleanup stack.
readability | Symbian (note) | Function names that end in a "D" indicate that the function call will result in the deletion of the object.
| Symbian (note) | When a function "`Leaves`", control is passed up the function call stack to the first call which was protected with a `TRAP` clause. The cleanup stack is then unwound, and all objects which have been pushed onto the cleanup stack since this `TRAP` clause are deleted. This means that in code that can leave, the only destructors that you can ensure are called, are for objects that can be pushed onto the cleanup stack, or which are members of other objects that have been pushed onto the cleanup stack, and so on, transitively.

### H

header files |  |
--- | --- | ---
See also files |
convention |  | In header files, use standard anti-nesting, for example:
    #ifdef __CMYCLASS__
    #define __CMYCLASS__
body of header
    #endif
Always use explicit access control specifiers. List the public members first, then the protected ones, then the private ones. List the data members in a group after the methods. Put any "special" methods first within each section (for example, `NewL` / `NewLC` / constructors / destructors / operators). Group methods by sets of functionality. Name variables in the function declaration. Group overridden methods together within each section, labelling which immediate base class they are from (via //from `CMyBase` Class), and do not specify the keyword virtual, for example:
    //from CCoeControl
    void Draw() const;
    //from MObserver
    void Notify();
    void StopObserving();
convention | S60 | Use `#ifndef` when including header files within header files.

### I

#include |  |
--- | --- | ---
convention |  | Put system includes first (using angle brackets), followed by local includes (using quotes).
convention | C++ | Prefer forward declarations to `#include` statements, otherwise you end up with horrendously long build times on larger projects.

inheritance |  |
--- | --- | ---
See also virtual functions |
maintainability | C++ | Never use multiple inheritance except for interfaces (that is, `mixin` classes). Interfaces must have no member data. However they need not be pure virtual; they may have trivial implementation of functions.
maintainability | C++ | Never use private or protected inheritance. Consider whether composition would be more appropriate.

invariants |  |
--- | --- | ---
See also assertions |
|  | See assertions.

### L

local variables |  |
--- | --- | ---
See also variables |
maintainability | C++ | Local variables should be defined as late as possible, that is near to their first use.
maintainability | C++ | Never use static local variables.

###

M

M classes |  |
--- | --- | ---
| Symbian (note) | M class objects cannot be passed or returned by value. The choice between pointer and reference should be made according to whether a `NULL` value is acceptable.

macros |  |
--- | --- | ---
See also functions |
reliability | C++ | Avoid macros. Any macros you do use should be all capitals, using underscores to separate words. Use `enums` and `const static` instead of `#defining` constants. Inline functions can replace many other uses of macros. `#ifdef DEBUG` is acceptable, as is the `ASSERT` family of macros.

member variables |  |
--- | --- | ---
See also variables |
reliability | C++ | It is better by far to encapsulate member data than return references to it . If you must return references to member data, it is better to return a `const` reference. If you must return a `non-const` reference, you need to provide both a `const` and a `non-const` (overloaded) accessor function, or you won't be able to call it from a `const` member function!
reliability | C++ | Whenever you delete member variables, you must set them to `NULL`. This is a safeguard against many nasty difficult to trace bugs.
maintainability | C++ | Never have public member data.

### O

operators |  |
--- | --- | ---
viability | C++ | Assignment operators must handle self-assignment, though this becomes mostly irrelevant in Symbian OS.

### P

parameters |  |
--- | --- | ---
readability |  | In source files, use the same parameter names as you had in the header file.
readability | C++ | Never use ellipsis notation, that is, `func(...)`.

pointers |  |
--- | --- | ---
reliability | C++ | Never use pointer arithmetic.
reliability | C++ | Never use pointer casts. Unfortunately, sometimes libraries you are using force you to cast return values. In this case encapsulate the cast in a function call, and use standard C++ casts rather than C style casts (for example, `dynamic_cast`).
reliability | S60 | Initialize all pointers to `NULL` (not `0`).
reusability | Symbian | Use descriptors and other specialized classes instead of pointers when storing data or handling strings.
convention | S60 | Check for non-null pointers via `if (ptr)` instead of `if(ptr!=NULL)`.

postconditions |  |
--- | --- | ---
|  | See assertions.

preconditions |  |
--- | --- | ---
|  | See assertions.

### R

R classes |  |
--- | --- | ---
See also destructors |
viability | Symbian | You cannot push R-class objects onto the cleanup stack, hence they must not have a destructor.
viability | Symbian | You shouldn't pass R class objects by value. Since R class variables are system resources you shouldn't make copies of them.
reliability | Symbian | R classes must initialize all member data in the constructor. You cannot rely on members being zeroed.
reliability | Symbian | R class objects must not be created via new.
| Symbian (note) | It is generally necessary to "open" and "close" R-type objects, and hence you see code like this:
    RFile file;
    file.OpenL();
    TRAPD(err,file.ReadL());
    if(err)
    {
    file.CloseL();
    User::Leave(err);
    }
    //etc. etc.
This is inefficient, and makes code quite unreadable, being (in effect) a return to the era of checking return values for error codes. There is a simple method for bypassing this, shown in the following example:
    class SRClassCleanup
    {
    public:
    static void OpenLC(RFile& aFile)
    {
    User::LeaveIfError(aFile.OpenL);
    CleanupStack::PushL(TCleanupItem
    (ReleaseRFileOnCleanup,&aFile));
    }
    private:
    static void ReleaseRFileOnCleanup(TAny* aObject)
    {
    REINTERPRET_CAST(RFile*,aObject)->Close();
    }
    //repeat for all R-Classes in your project.
    };
Then we can simplify the previous example to the following (assuming we've derived from `SRClassCleanup`):
    RFile file;
    OpenLC(file);
    file->ReadL();
    //etc. etc.
    CleanupStack::PopAndDestroy();//close file

resource files |  |
--- | --- | ---
convention | Symbian | Place resource structures in `.rh` file.
convention | Symbian | In a resource file, write resource names in lower case.

### S

statements |  |
--- | --- | ---
reliability | C++ | Never modify two different objects in the same statement.
readability | C++ | Break statements, multiple returns, and even continue may make your code clearer. Use them when they make your code clearer. Don't use them if they make it less clear!

strings |  |
--- | --- | ---
reusability | Symbian | Always use resource files instead of string constants.

structs |  |
--- | --- | ---
readability | C++ | Always use `class` instead of `struct`.

### T

T classes |  |
--- | --- | ---
viability | Symbian | Since T class objects cannot be pushed onto the cleanup stack, they must not have a destructor as you cannot ensure that it is called in all circumstances.
viability | Symbian | T class objects must not be created via new.
| Symbian (note) | T class objects are returned by value, and passed by reference or value.

TBool types |  |
--- | --- | ---
| Symbian (note) | The compiler will not allow you to compare TBool types with `ETrue` and `EFalse`. Instead consider, for example, `if ( !Visible() ) )`.

templates |  |
--- | --- | ---
reliability | C++ | Templates should be used only for defining universal containers. Any template should be tested carefully on the target platform.
reliability | C++ | Templates should never be used in conjunction with virtual functions.

types |  |
--- | --- | ---
viability | Symbian | Always use Symbian OS types, for example, `TInt` instead of `int`.
viability | Symbian | Don't use the explicit type forms (for example `TInt16`) except in rare circumstances (for example reading from resource files).
readability | C++ | For conversion between base types, always use explicit casts - it clarifies your code and removes warnings.
convention |  | The name for the enumeration type should have a capital `T` prefix, the enumeration members should have a capital `E` prefix. Use relevant, meaningful, and unambiguous names for `enums`.

### U

unions |  |
--- | --- | ---
readability | C++ | Never use a `union`, unless you are forced to when writing low-level machine-specific code.

### V

variables |  |
--- | --- | ---
See also local variables, member variables |
reliability | C++ | Only a single variable declaration should be made per statement.
convention | Symbian | Put the pointer or reference indicator next to the type name, with no separating space.
convention | Symbian | Variable names start with (some or none) Symbian OS prefixes (i, a, C, M, T, R, E, K, S), followed by concatenated words (that is, no underscore separator), the first letter of each word being capitalised, followed by (possibly) Symbian OS postfixes (L, C, D). The only exception to this rule is that local variables have a lower case first letter to distinguish them from functions. Don't use numbers or abbreviations in names (except for test code).
convention | Symbian | Variable names should be abstract nouns like `windSpeed`, `windowPosition`. Make them long enough to be descriptive (although it is fine to use variables like i or j within a for loop).
convention | Symbian | Local variable names should start with a lower case letter.
convention | Symbian | Parameter names should be prefixed with a lower case "a", followed by an upper case letter.
convention | Symbian | Member data names should be prefixed with a lower case "i", followed by an upper case letter.

virtual functions |  |
--- | --- | ---
See also functions, inheritance |
viability | C++ | You should never call a virtual function from within a constructor or destructor.
reliability | C++ | Never overload virtual functions.
reliability | C++ | When implementing a virtual function you often need to call the base class implementation. When you scope the call you should use your immediate base class:
    SportsCar::DoSomething()
    {
    FastCar::DoSomething();
    //code here
    }
reliability | S60 | Virtual functions should not be inline, except for destructors.
maintainability | C++ | When implementing a virtual function you often need to call the base class implementation. This should normally be done first or last:
    SportsCar::DoSomething()
    {
    FastCar::DoSomething();
    //code here
    }
or
    SportsCar::DoSomething()
    {
    //code here
    FastCar::DoSomething();
    }
and not:
    SportsCar::DoSomething()
    {
    //code here
    Car::DoSomething();
    //some more code here
    }
readability | C++ | Never change the visibility (public/protected/private) when overriding a virtual function.
reliability | C++ (note) | In an overridden function you cannot make any more assumptions than the preconditions of the base class implementation and your own class Invariants.