Download (direct link):
• The API should provide the appropriate level of encapsulation, i.e. member data hiding.
• Friendship of a class should be kept toaminimum in order to preserve encapsulation.
• Polymorphism should be used appropriately and correctly.
• A class should not have exported inline methods.
• A non-derivable class with two-phase construction should make its
constructors and ConstructL() private.
• const should be used where possible and appropriate.
• Overloaded methods should be used in preference to default parameters.
• Each C class should inherit from only one other C class and have CBase as the eventual base class.
• Each T class should have only stack-based member variables.
• Each M class should have no member data.
• Header files should contain "in-source" documentation of the purpose of each class.
• The inclusion of other header files should be minimized by using forward declaration if required.
• Header files should include the correct #ifndef...#define... #endif directive to prevent multiple inclusion.
• The number of IMPORT_C tags should match the corresponding EXPORT_C tags in the .cpp file.
• Comments should match the code.
• Comments should be accurate, relevant, concise and useful.
• Each class should have "in-source" documentation of its purpose in header file.
• Each method should have "in-source" documentation of its purpose, parameters and return values in the .cpp file.
• A CBase-derived class does not need explicit initialization.
• Member data of T and R classes should be explicitly initialized before use.
• Member data should be initialized in the initializer list as opposed to the body.
• A C++ constructor should not call a method that may leave.
• Two-phase construction should be used if construction can fail with anything other than KErrNoMemory.
• NewL() and NewLC() methods should wrap allocation and construction where necessary.
• All heap-allocated member data owned by the class should be deleted.
• There should be a NULL pointer check before any dereference of a member pointer.
• Member pointers do not need to be set to NULL after deletion in the destructor.
• Member pointers deleted outside the destructor should be set to NULL or immediately re-assigned another value.
• A destructor should not leave.
Allocation and Deletion
• For a new expression, either use new (ELeave), or check the return value against NULL if leaving is not appropriate.
• For a call to User::Alloc(), either use AllocL(), or check the return value against NULL if leaving is not appropriate.
• Objects being deleted should not be on the cleanup stack or referenced by other objects.
• C++ arrays should be de-allocated using the array deletion operator, delete  <array>.
• Objects should be de-allocated using delete <object>.
• Other memory should be de-allocated using the method User::Free (<memory>).
Cleanup Stack and Leave Safety
• If a leaving method is called during an object's lifetime, then the object should either be pushed on to the cleanup stack or be held as a member variable pointer in another class that is itself leave-safe.
• An object should not simultaneously be owned by another object and held on the cleanup stack when a leaving method is called.
• Calls to CleanupStack::PushL() and CleanupStack::Pop() should be balanced (look out for functions that leave objects on the cleanup stack, such as NewLC()).
• If possible, use the CleanupStack::Pop() and PopAndDe-stroy() methods which take pointer parameters, because they catch an unbalanced cleanup stack quickly.
• Where possible, use CleanupStack::PopAndDestroy() rather than Pop() followed by delete or Close().
• Local R objects should be put on the cleanup stack using Cleanup-ClosePushL(), usually after the object has been "opened".
• Errors caught by a TRAP harness that are ignored must be clearly commented and explained.
• The code within a TRAP harness should be able to leave.
• Error processing after a TRAP that ends with an unconditional User::Leave() with the same error code should be re-coded using the cleanup stack.
• Use the LeaveScan tool to check source code for functions that can leave but have no trailing L.
Loops and Program Flow Control
• All loops should terminate for all possible inputs.
• The bracing should be correct on if.. .else statements.
• Optimize loops by using the clearest type (do.. .while or while) in each case.
• There should be a break statement for each case of a switch statement - or a comment if a flow-through to the next case statement is meant.
• A switch statement shouldn't contain case statements that return from the function unless every case in that switch statement contains a return.
• A switch statement should be used to indicate state control. Each case statement should contain only a small amount of code; large chunks of code should be moved into separate functions to maintain the readability of the switch statement.