Вы находитесь на странице: 1из 36

EON Technologies Inc.

Guidelines for Eon Technologies Projects

Coding Conventions for C++


Document Version 0.9 Mart 2001

1 Coding Conventions for C++

EON Technologies Inc. Table of Contents


Guidelines for................................................................................................................1 Eon Technologies Projects...........................................................................................1 Document Version 0.9 Mart 2001.................................................................................1 Table of Contents.........................................................................................................2 Preface.........................................................................................................................3 The Structure of the Document.....................................................................................3 General Guidelines.......................................................................................................4 Standard C++, Win32 and MFC....................................................................................4 Redundant mechanisms...............................................................................................4 The Choice of Names...................................................................................................5 General Conventions....................................................................................................5 Source files...................................................................................................................5 Portability issues.......................................................................................................5 Data Types...................................................................................................................6 Classes.....................................................................................................................6 Structures, Enumerations, Typedefs.........................................................................7 Named values of enumeration...................................................................................7 Variables.......................................................................................................................8 Common variables....................................................................................................8 Global variables.........................................................................................................8 Member variables......................................................................................................9 Arrays........................................................................................................................9 Preprocessor..............................................................................................................10 Required preprocessor checks in header files.........................................................10 Methods (functions)....................................................................................................11 Shape of Code............................................................................................................12 The Use of Operators.................................................................................................13 Identing Code.............................................................................................................14 Sequence of Declarations in the Class.......................................................................15 Comments..................................................................................................................15 General Guidelines.....................................................................................................15 Automatic generation of documentation..................................................................16 Scope of commenting.................................................................................................17 Shape of common code comments.........................................................................17 Introduction comment .............................................................................................18 Commenting for autoduck parsing..............................................................................20 Commenting a module (file)....................................................................................20 Commenting a class................................................................................................22 Commenting class functions in detail......................................................................24 Appendix.....................................................................................................................26 A Common Variable Names and Prefixes................................................................26 Common Variable Names.......................................................................................26 Prefixes for Variable Types.....................................................................................28
2 Coding Conventions for C++

EON Technologies Inc.


B - Some Programming Styles and Idioms.................................................................31 Do not include header to header when you need a pointer to class........................31 Avoid circular class references................................................................................32 Use of mix in classes and *real* inheritance...........................................................33 Error Handling.........................................................................................................34 Smart stacked variables..........................................................................................36

Preface
This document provides conventions for writing C++ code. Coding conventions described here should be adopted when creating, changing and refactoring the C++ code for Eon Technologies. Conventions are separated to two groups:

Requirements and Recommendations.

There are only handful basic requirements, which you are required to follow. They were carefully chosen not to affect the productivity. The objective for the requirements is to ensure basic unique shape of all the C++ code, produced by or for Software System Solutions. As a foil to requirements, recommendations are not "de iure" standard, but selected best current practices. You are free to make your own decisions about them. You are free to ignore them where they would impose limitations and/or any kind of penalties to your efficiency. The objective of recommendations is to promote coding styles, based on experience, idioms and patterns that could be described preventive and lead to concise, solid and reliable code. Coding conventions are a living language. As programming knowledge will grow new idioms will find their way into this document. Therefore it is by no means thought of as complete. If you find out new facts or have an idea about how to improve it, you are encouraged to come forward with your proposals for improvements.

The Structure of the Document


The document is structured into five main parts.

General Guidelines, Choice of Names, Shape of Code, Comments and Appendix.

General Guidelines chapter discusses latest development in C++ and MS community and about evolution of C++ programming in general. Choice of Names chapter prescribes naming for variables, methods, classes, enumerations, structures, file naming conventions and conventions about naming other elements of C++ source. Shape of Code chapter prescribes spacing and line breaking in your code. Comments

3 Coding Conventions for C++

EON Technologies Inc.


chapter prescribes head and tail for all source files, mandatory and optional comments and commenting for automatic generation of documentation. All that is not described in first four chapters is added to the Appendix section. Each chapter contains a list of guidelines: requirements and recommendations. Additional notation is used at the left side of the text to present requirements and recommendations.

at the left side of text block marks requirement section whilst,

marks recommendation section.

General Guidelines Standard C++, Win32 and MFC


In 1998 C++ was standardized by ANSI. With the standard came conventions that were used by the contributors to the standard or strong authors in the field of C++: Stroustroup, Meyers, Lakos But as C++ was developed as platform independent programming language these conventions did not take into consideration existing widely spread frameworks and conventions such as: Win32 conventions used with Win32 API and conventions used with the Microsoft Foundation Classes framework (MFC in following text). As C++ projects may vary it is impossible to give guideline about which style to use. So as a general rule of thumb you are required to adopt the style of your environment if the environment already provides you with more then 50% of code. For fairly independent projects or new projects use prescribed style instead.

Redundant mechanisms
MFC and Standard C++ with STL both introduce their own solutions for some commonly used abstractions in programming:

Container classes (lists, dictionaries, etc.), RTTI, Exceptions.

In general you should apply the mentioned rule of thumb.

You are encouraged to use Standard C++, including new powerful features: new casts, namespaces, templates and the STL...
4 Coding Conventions for C++

EON Technologies Inc. The Choice of Names General Conventions


All names are in English language. Letters of English alphabet and numbers are allowed in names of all identifiers. Underline symbol (_) is allowed on occasions described by the conventions.

Source files
In general a class should be stored in two files. In header file (with .h extension), which contains declaration of the class and in implementation file (with .cpp extension). Chosen filenames can follow long filename convention. You are allowed to use basic letters of English alphabet in names of files. You are also allowed to use numbers, underline symbol (_) and ONE AND ONLY ONE dot symbol, which must have a function of dividing the name from the extension. Use of spaces is not allowed in file names. For line breaking in source files CR+LF combination must be used.

Portability issues
Using prescribed naming convention (including VC++ conventions) will make your files portable between various platforms (with respect to line breaking characters).

When programming under Windows you MUST use VC++ convention. It prescribes capitalized words in name.

Samples:
UserAuthenticationSystem.cpp User Authentication System.cpp user_authentication_system.h UserAuthenticationSystem.h CommonObjectBroker.cpp ObjectValidator.cpp objectValidator.h // OK, MFC // INVALID // OK, NOT USING MFC // OK, MFC // OK, MFC // OK // OK, NOT USING MFC

It is warmly recommended that you use VC++ file naming conventions on all platforms for their generality. By following this recommendation problems will be avoided when unzipping your files on another platform.

5 Coding Conventions for C++

EON Technologies Inc. Data Types


Classes
The name of the class should be a noun. All words in the class should start with a capital letter. It is good practice to hint a name from which class it is derived in class name. For example: if we wanted to declare Yes/No dialog, our class name would be YesNo, but with hint it would be YesNoDialog.

For Windows programming class names MUST be prefixed with C. Samples:


class CQuitDialog; class QueueObserver; class CSettingsManager; // OK, WINDOWS SOURCE // OK, NON WINDOWS SOURCE // OK, WINDOWS SOURCE

In non-Windows sources classes, which are derived from std. library classes, can use same conventions as the library.

Samples:
class QueueException : public exception; // OK class queue_exception : public exception; // OK, using std. library convention class MyList : public list<MyObj>; // OK

Exception are interface classes (also applies to pure virtual classes!) which are prefixed with capital letter I, since this is commonly accepted standard.

Samples:
class IConnectionPoint class IUserManager class IMessageQueue

6 Coding Conventions for C++

EON Technologies Inc.


Structures, Enumerations, Typedefs
When programming in Windows, structures must be prefixed by capital S letter, typedefs by capital T and enumerations by capital E letter. This way classes, typedefs, structures and enumerations have consistent naming.

Samples:
class CFile; struct SConnectionPort { unsigned data:8; unsigned parity:1; unsigned control:2; }; typedef SConnectionPort TConnector; TConnector conr; // OK

enum ETaskType { copyFile, installFile }; // OK, see Named values of enum.

Named values of enumeration


Enumerations also have named values. First word of named value should be in lowercase others should be capitalized.

Sample:
enum ETaskType { copyFile, installFile};

7 Coding Conventions for C++

EON Technologies Inc.

Variables
Common variables
The name of the variable should describe the intention (purpose) of variable with respect to name length. Best names are from 8 to 16 characters long and descriptive. If variable name is composed of many words then all words in variable must be capitalized. In addition a name must be prefixed with it's type (Hungarian notation)! Sample:
int iLinesPerPage;

A list of prefixes for standard C++ types and common Windows types is given in Appendix A.

If variable is of type custom class then the prefix is optional. It can be composed as two to three letter abbreviation, it can be generic a or obj prefix or no prefix. Samples:
CConnection cnPersonDatabase; CDynamicAllocator DynAllocr; CActiveFolder objFolder; CPerson aPerson;

Global variables
Global variables must be prefixed with g_ or gl_.

Samples:
CPermanentConnection gl_cnSettingsDatabase; CappSingleton g_objApplication;

8 Coding Conventions for C++

EON Technologies Inc.


Member variables
Class and structure member variables should be prefixed or post fixed.

For Windows source class member must be prefixed with m_.

Samples:
// Windows class class CMyClass { int m_iMemberVariable; char m_cMemberVariable; }

In non Windows source variable can be prefixed or (recommended, due to compiler's usage of prefix) post fixed with an underline.

Sample:
// Generic class class GenericClass { int iMemberVar_; char cMemberVar_; }

Prefix or postfix notation are both correct for generic classes. It is good to decide for one in the scope of same file.

Arrays
Array is a special kind of variable. It follows same naming convention. The name of array must use plural instead of singular.

Samples:
CList<Person&, Person&>arrPersons; vector<CCar>vctCars; // Cars, with optional type prefix int iSquares[]={1,2,4,8,16,32,64,128};

9 Coding Conventions for C++

EON Technologies Inc. Preprocessor


You are discouraged to use preprocessor in all but the following cases:

Conditional compiling and Include check (for header files).

Instead of macros you should use inline functions and instead of preprocessor constants you should use namespace constants, class constants or global constants. Words in preprocessor symbols can be divided by underline symbol. You may prefix constants with _, to differentiate them from preprocessor macros.

All preprocessor symbols must be capitalized.

Samples:
#define MAX(a,b) (a > b ? a : b) #define _PI 3.14 #define _MAGIC 1234

Required preprocessor checks in header files


Following preprocessor checks are required in every header file. Header files MUST test if they were already included using the preprocessor. MFC header files MUST add directives to enable memory leaks tracing!

Sample:
// MFC directives #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif // include test #if !defined(_OBJBROKER_H) #define _OBJBROKER_H ... body of objbroker.h file ... #endif

10 Coding Conventions for C++

EON Technologies Inc. Methods (functions)


First letter of every word in global as well as member method name must be capitalized.

First word in method should be a verb explaining what the method does. Further text can contains nouns on which method operates.

Samples:
GetUserInfo(LONG lUserObjectID); DeleteAll(void);

A special kind of method is method returning Boolean value. This method can start with prefix is.

Samples:
IsValidZipCode(...); IsEmpty(...);

11 Coding Conventions for C++

EON Technologies Inc.


Another special type of methods worth mentioning are get/set methods for accessing class properties. As guideline (but broken in MFC and thus optional) class properties (variables) should be private and only accessible trough get/set methods.

Sample:
class CItem { private: CString m_sDisplayName; public: CString DisplayName(); // get method void DisplayName(CString sDisplayName); // set method }

The second way is to add noun Get and Set in front of the property name.

Sample:
class CItem { private: CString m_sDisplayName; public: CString GetDisplayName(); // get method void SetDisplayName(CString sDisplayName); // set method }

Note: MFC's CString should be treated as basic type structure.

Private classes as class members are exception to the rule. They should not be exposed trough get/set properties since that would violate encapsulation. Instead delegation should be used as access technique.

Sample:
class CItem { private: CSubitem m_objSubitem; public: DoSomething() { m_objSubitem.DelegatedDoSomething() }; }

Shape of Code
12 Coding Conventions for C++

EON Technologies Inc.


In general preferred way of indenting your code is with spaces instead of tabs since tabs will not look well (same) on all editors. However due to the fact that many developers use tabs they are also allowed.

The Use of Operators


Comparison operators, assignment operators, binary operators + and and shift operators should be divided from the rest of the code with spaces.

Samples:
if ( a == b ) DoSomething(); b = c; d << f;

This rule does not apply to other operators.

Samples:
a++; // NOT a ++ !!! b = -c; if ( !b ) DoSomethingElse();

13 Coding Conventions for C++

EON Technologies Inc. Identing Code


Code should be indented by one tabulator (or by four spaces) after each {. It is up to programmer to decide whether to put { at the end of previous line or at the beginning of new line. Recommended bracing style is given in the sample bellow.

Sample:
if ( m_nWatchesNumber < 0 ) m_hResultError = ERROR_EMPTY_WATCHER; else { m_hResultError = ERROR_NO_NOTIFIER; m_IDs.RemoveAll(); for ( int nCount = 0; nCount < m_nWatchesNumber; nCount++ ) { if ( m_pWatchNotifier[nCount].GetRegKey() == 1 ) { m_IDs.Add(m_pWatchNotifier[nCount].GetWatchID()); m_hResultError = ERROR_SUCCESS; bFilled = TRUE; } else { m_pWatchNotifier[nCount].SetRegKey(0); m_bHasZero = TRUE; } } }

14 Coding Conventions for C++

EON Technologies Inc. Sequence of Declarations in the Class


Inside the class the following sequence of declarations (based on protection level) should be used:

Public members, Protected members, Private members.

Within one level of protection the following sequence should be used:


Constructors, destructors Attributes, properties Operations Overridables Implementation

Sample:
class MyClass { public: MyClass(void); // ctor virtual ~MyClass(); // dtor protected: int _iSomeMember; // attribute virtual void ExecuteOperation()=0; // overridable private: bool _bPrivate; // attribute void DoSomething() { // implementation Something(); } }

Comments General Guidelines


C++ notation with two slashes should be used instead of the old C notation. There is no general rule for how much commenting is necessary. Rule of the thumb is that for every four lines of code there is a need for a line of comment. This rule should not however support sloppy coding. Code should be written in concise way, expressive names used to demonstrate intentions. If at some time some code needs excessive commenting then it should instead be refactored to be self-explaining.
15 Coding Conventions for C++

EON Technologies Inc.


Automatic generation of documentation
Special tags can be used inside comments, which enable the Autoduck software tool creating documentation from comments by parsing source code. Autoduck software is a powerful command line tool that can be used to create customized HTML, Windows HELP and RTF format documentation of code. The powers of autoduck are:

Templates for documentation are fully customisable, Documentation can be created during the build process by adding several commands to the makefile or adding post-build steps to IDE (for example a batch file running autoduck and copying documentation to appropriate directory).

By using Autoduck with it's search and indexing mechanisms there is no need for additional code documentation beyond detailed design document since all documentation is created directly from source code by every build. Proposed procedure for commenting the code is: 1. Write the module. 2. Test it. 3. And only after you have a candidate for review (i.e. 1.0) comment it. This way no excessive changes will be needed to comments as you change the code during development.

16 Coding Conventions for C++

EON Technologies Inc. Scope of commenting


Following should be commented in source code:

All interfaces to the outside world!, Most classes, especially classes that will interact with other people's code, by documenting in detail: class purpose, properties and methods, All functions that are visible beyond the scope of a file in which they are declared, Data structures, Special algorithms used in class (at the top of file), All files (by attaching special comment at the top), common code (hint: control statements)

Every source file (every header file and every implementation file) must also have an introduction comment explaining basic information about the file.

Shape of common code comments


Line should be commented at it's end, if possible subsequent comments should be indented.

Sample:
DoSomething(); // now do something

SoSomethingElse(); // now something else, idented

If comment can't be written in one line it should be written in many lines and idented.

Sample:
DoSomething(); // comment for single line of code stretching over // multiple lines

In case line or comment is too long to be in the same line then comment should be written at the top of code indented with it. Sample:
for (int i = 1; i < 100; i++) // comment for code following DoSomethingVeeeeeeeeeeeeeeeeeerrrrrrryyyyyyyyyyLooooooooonnnnnnng();

17 Coding Conventions for C++

EON Technologies Inc.


Introduction comment
Top of source file
At the top of every C++ file there should be a heading with the following information:
////////////////////////////////////////////////////////////////////// // // @doc // // @module objbroker.cpp ObjectBroker implementation. | // // This file implements ObjectBroker class. ObjectBroker class takes // care for persistence of all objects, derived from PersistentObject. // It provides base mapping mechanisms. Brokers for different mappings // should use this class as base class and derive from it. // // Example: // // // // Copyright 2000 Eon Technologies, // All Rights Reserved. // // Feb the 12th Leonid Doe (leo@abd.com) // // // // NOTE: // // ////////////////////////////////////////////////////////////////////// Special algoritm used... 1.0 Unit has been created and tested. 1.1 Added Seek method to the class. Tested. // Feb the 16th Willy Markwald (willy@abb.com) class RDBObjectBroker : public ObjectBroker relational database mapper

Some revision control systems add changes to module automatically by providing tags such as $Log:$ in the head of file. However since revision control system has not been chosen yet versioning has to be done manually.

18 Coding Conventions for C++

EON Technologies Inc.

Bottom of source file


Last three lines of file must be:
////////////////////////////////////////////////////////////////////// // end of objbroker.cpp //////////////////////////////////////////////////////////////////////

19 Coding Conventions for C++

EON Technologies Inc. Commenting for autoduck parsing


Autoduck comes with sample files and help so no in depth explanation of autoduck is given here. However basic conventions about the desired minimum commenting are given for autoduck. Very important notice: Commenting or using Autoduck is optional !

Commenting a module (file)


The two tags used for commenting a file are @doc comment and @module comment.

Sample:
////////////////////////////////////////////////////////////////////// // // // // // // // // // // // // // // // // // ////////////////////////////////////////////////////////////////////// NOTE: / Feb the 16th Stilian (stil@eontechnologies.com) 1.0 Tested and released. Copyright 2000 Eon Technologies, All Rights Reserved. This file defines the user class. This class is used as authentication object for the user. @module User.h - User class definition. | @doc

The one of importance is the module tag. It accepts two entries following it. The abstract and the description, divided by a standard autoduck separator |.

20 Coding Conventions for C++

EON Technologies Inc.


The result of the upper code after parsed with autoduck is a new entry under modules section of documentation:

Module User.cpp - User class implementation


Filename: C:/JOB/EON/AUTODUCK/TEST/USER.CPP Description This file implements the user class. This class is used as authentication object for the user. Copyright 2000 Eon Technologies, All Rights Reserved. Feb the 16th leonid (Leonid@eontechnologies.bg) 1.0 Tested and released. NOTE: /

21 Coding Conventions for C++

EON Technologies Inc.


Commenting a class
You comment a class by using several tags that the Autoduck software supports. Depending on desired level of detail, you might want to comment only header file definition or you might also comment implementation. . First part of commenting a class is commenting class definition (inside header file). The following example demonstrates desired tags for creating EON compliant documents:
// @class User | User authentication object. User must own this object // to enter the system. // @base public | Person class User : public Person { //@access Public members. public: //@cmember Constructor. User(); //@cmember Destructor. virtual ~User(); //@cmember Sets login name. void Login(std::string sLogin); //@cmember Gets login name. std::string Login(void); //@cmember Sets password. void Password(std::string sPassword); //@cmember Gets password. std::string Password(void); //@access Private members. private: //@cmember User password. std::string _sPassword; //@cmember Login name of the user. std::string _sLogin; };

The tags uses are @class descriptor, @access descriptor and @cmember (class member) descriptor. These tags all describe the code that follows and must be put directly preceding it or else will be ignored or error reported. After parsed with autoduck the output is:
22 Coding Conventions for C++

EON Technologies Inc. User Class


class User: public Person User authentication object. User must own this object to enter the system. Defined in: C:/JOB/EON/AUTODUCK/TEST/USER.H Class Members Public members. User() Constructor. virtual ~User() Destructor. void Login(std::string sLogin) Sets login name. std::string Login(void) Gets login name. void Password(std::string sPassword) Sets password. std::string Password(void) Gets password. Private members. std::string _sPassword User password. std::string _sLogin Login name of the user.
Commenting template classes is described in autoduck documentation. Commenting important functions of the class can go to details (commenting each parameters). Same is possible for commenting enumerations.

23 Coding Conventions for C++

EON Technologies Inc.


Commenting class functions in detail
Class functions can be commented as details of class or as separate topics. They can be commented in header or in implementation file. Sample bellow demonstrated the usage of @cmember tag for short descriptions in header file. For longer function description one can use tag @mfunc (member function). This should be used on non-trivial functions.

Sample:
// code inside of User class //@mfunc string | User | Login | This function gets the //login name for the user object. std::string Login(void);

Result:

User::Login
std::string User::Login(void) This function gets the login name for the user object. Defined in: C:/JOB/EON/AUTODUCK/TEST/USER.H
For even more details one can use separate comment in implementation (cpp) file in front of function body.

24 Coding Conventions for C++

EON Technologies Inc.


Following sample demonstrates usage of detailed description in implementation file.

Sample:
////////////////////////////////////////////////////////////////////// // // // // // // // // // @ex The following example demonstrates how to use the function: | // string sLogin="Tomaz"; // User aUser; // // set user login name // // // // ////////////////////////////////////////////////////////////////////// void User::Login(string sLogin) { _sLogin = sLogin; } @todo Nothing to do. But a nice tag demonstration. aUser.Login(sLogin); @rdesc Function returns no value. @parm string | sLogin | Specifies new login name. @mfunc This function sets user object login name given by parameter <p sLogin>.

25 Coding Conventions for C++

EON Technologies Inc.


Result:

User::Login
void User::Login(string sLogin) This function sets user object login name given by parameter sLogin. Defined in: C:/JOB/EON/AUTODUCK/TEST/USER.CPP Return Value Function returns no value. Parameters sLogin Specifies new login name. Example The following example demonstrates how to use the function:
string sLogin="Tomaz"; User aUser; // set user login name aUser.Login(sLogin);

To Do Nothing to do. But a nice tag demonstration.

Appendix A Common Variable Names and Prefixes


Common Variable Names
Following is a list of names commonly used in programs. The ? in front of the name stands for Hungarian notation prefix and depends on the type of variable. Common names for variables nFirst Index of the first element in the field, pFirst for STL iterators nLast Index of the last element in the field, pLast for STL iterators ?Sum Sum of elements, the ? is prefix based on type, for example fSum, nSum, lSum ?Avg Average ?Max Maximum value ?Min Minimum value nNum Number of data, can be lNum if LONG nLength The length of field, list, set ?Next Index OR value of next element in the set ?Prev Index OR value of previus element in the set ?Cur Index OR value of current element in the set ?Save Saved value ?Tmp Temporary value ?Src Source, in comparision and transfer routines ?Dst Destination, in comparision and transfer routines Samples:
26 Coding Conventions for C++

EON Technologies Inc.


dSum=0L; nNum=0; pFirst=list.begin(); for (pCur=pFirst; pCur=list.end(); pCur++) { dSum+=*pCur; dTmp=*pCur; // whatever we need this for... nNum++; } dAvg=dSum/static_cast<double>(nNum);

27 Coding Conventions for C++

EON Technologies Inc.


Prefixes for Variable Types
The following table is a list of prefixes according to the Hungarian notation.

Standard C++ types


C++ types char int long boolean pointer void float double unsigned object string enum function Samples:
char * pchName; // correct char * szName; // also correct char * pszName; // problematic, since it is not consistent but correct boolean bFlag; unsigned long ulValue, lValue2; // both correct, u is optional void * pvMemBlock; CPerson aPerson; CCar objCar;

ch n l b p v (pointer to void pv) f d u (optional) a, obj (optional) s, str e fn

28 Coding Conventions for C++

EON Technologies Inc.


Common Windows Types
Common Windows types LPTSTR sz or lpsz LONG l WORD w DWORD dw HANDLE h POINT pt SIZE size RECT rect BOOL b UINT n Samples:
LPTSTR szUserName; LONG lVal; DWORD dwBytesRead; SIZE size; RECT rectClient; UINT nCur;

Common MFC Types


Common MFC types CString s, str CRect rct CDC dc CRegion rgn CWindow wnd CView vw CSize siz Control ctr Samples:
CString sUserName; CDC *pdcClient;

29 Coding Conventions for C++

EON Technologies Inc.


Resource Types
Resource types IDC_ Control within dialog IDS_ String IDR_ Multiple valued resource (i.e. MFC doc-view app has shared menu+string table resource value) IDB_ Bitmap IDC_ Cursor (not within dialog) IDI_ Icon IDD_ Dialog HIDD_ Dialog resource help context HID_ Command help context ID_ Command IDP_ Message box prompt HIDP_ Message box help context

Samples:
IDS_FILE_NOT_FOUND ID_FILE_OPEN IDC_EDIT_USERNAME IDC_CBO_USERGROUP IDB_COMPANY_LOGO

30 Coding Conventions for C++

EON Technologies Inc. B - Some Programming Styles and Idioms


Usage of following styles and idioms is optional. This section is composed mostly of personal opinions of people in EON. You are encouraged to contribute your tips and tricks of more effective programming.

Do not include header to header when you need a pointer to class


Typically whenever you use a class in implementation file you include it in header file. However, this is not always necessary. Sometimes it adds to long compile times. Here is an advice how to cut down compile time.

Following is a typical code fragment in header file:


#include "Person.h" class Task { private: Person* _ResponsiblePerson: }

In this situation the compiler needs not to calculate the size of Person to reserve space for it inside the class since it only reserves space for pointer. And it knows the pointer's size. Hence you do not need to include the Person header file. You just need to declare the name. The same is true for the reference (&) since the reference is nothing more than constant pointer.

The code can be rewritten as:


class Person; class Task { private: Person* _ResponsiblePerson: }

By including person.h only to implementation (.cpp) file you effectively assist the compiler in pre-compilation of header files.

31 Coding Conventions for C++

EON Technologies Inc.


Avoid circular class references
Circular referencing happens when a class references class that refences another class that references the first class. It can be direct (involving just two classes) or indirect (circular over many classes). It makes hierarchical unit testing difficult. Instead of writing a simple test program for bottom units and then building further integration tests on dependencies to already tested units you have to test every class in environment of untested dependent classes.

Object 1

Object 2

Object 3

Figure 1. - Indirect circural dependencies between classes

32 Coding Conventions for C++

EON Technologies Inc.


Use of mix in classes and *real* inheritance
We strongly recommend against using multiple inheritance. One should differentiate between true implementation inheritances and mix in classes (interface inheritances). Implementation inheritance should rarely derive from more then one class. Implementation inheritance translates to IS-A relationship.

Sample:
class Person { }; // user is a person with login and password class User : public Person { string sLogin_; string sPassword_; };

Mix in class is a pure virtual and is a technique used to "demand" interface from certain class. It should be recognizable by class name which should not be a noun but instead behaviour descriptor (an adjective), such as: Serializable, Persistent, Listable,...

Sample:
// listable is an interface, not a class class DynamicallyCreatable { virtual void Create()=0; } // using mixin instead of real inheritance class Person : public User, public DynamicallyCreatable { // this class is forced to implement interface DynamicallyCreatable // i.e. the method Create() }

A rule is that first inheritance is *real* inheritances and follow inheritances are mix-ins.

Sample:
class User : public Person, public DynamicallyCreatable, public Persistent { }

33 Coding Conventions for C++

EON Technologies Inc.


Error Handling
For error handling inside C++ exceptions should be used rather then return codes from functions. This technique is optional.

Exceptions
Exceptions are powerful and structured mechanism that makes your code concise and easier to understand. Here is an example of code that does not use exceptions:
void fn1() { if (fn2()) { ok(); } else { ReportError(); } } boolean fn2() { if (fn3()==1234) return true; else return false; } int fn3() { if (fn4()!=2) return 1234; else return 4321; } int fn4() { return random()*2+1; // 1 or 2 }

Typically in your program you might have hierarchy of calls. If return codes are used as mechanism to return errors then checks have to be made throughout hierarchy and error codes translated several times to come to the top hierarchy.

The situation becomes even worse when error handling has to consider other people's object hierarchies.

34 Coding Conventions for C++

EON Technologies Inc.


With structured exception handling one has ability to catch exception at the desired level and if it is thrown at the bottom it will be (if not caught) automatically be propagated to the top level. Here is an example of preceding code fragment using exceptions.
void fn1() { try { fn2(); ok(); } catch (MyException& e) { ReportError(); } } void fn2() { fn3(); } void fn3() { fn4(); } void fn4() { if (random()*2+1 == 2) throw MyException("Something went wrong"); }

There is however penalty on exceptions. They are C++ mechanism and should not cross C++ boundaries. When working with COM one should always make sure that all exceptions are caught and translated to OLE errors before application boundaries are crossed.

35 Coding Conventions for C++

EON Technologies Inc.


Smart stacked variables
One common technique when using exceptions is to use so-called smart stacked variables such as auto_ptr (or CComPtr). The main idea is to put objects on stack by declaring them as private variables. After exception occurs stack is unwinded and destructors are called. This way objects can execute the clean up procedures inside their destructors. An example of smart variable could be transaction processor in following sample. Sample:
class Transaction { public: Transaction(); // intelligence in destructor virtual ~Transaction() { if (!bCommited_) Rollback(); } void Commit(); void Rollback(); private: boolean bCommited_; }

You would use this class as follows:


void PerformTransactionedDatabaseOperation() { Transaction trans; try { PerformDatabaseOperation(); // can throw exception } catch (DatabaseException &dbe) { ReportError(dbe); throw; // propagato to the caller } // if exception was thrown function will exit but destructor for // trans will still be called and transaction will automatically // rollback. }

36 Coding Conventions for C++

Вам также может понравиться