Google
 

วันอังคารที่ 5 มิถุนายน พ.ศ. 2550

C++ Coding Standard Part 3

Part III
Language Directives and Best Practices


Chapter 6
Take benefit from C++

1. Be Const Correct
C++ provides the const keyword. This makes it possible to indicate that a method doesn’t modify
the objects that it receives as parameters. Using const in all the right places is called "const
correctness". It’s hard at first, but using const really tightens up your coding style. Const
correctness grows on you.
If you’re in the darkness about what Const Correctness exactly is, read the relevant section in the
C++ FAQ
2. Use Streams
Programmers that move from C to C++ find IO stream strange and prefer the familiarity of good old
stdio. printf and its derivates seem to be more convenient since they are well understood.
However when you use these old idioms, you throw away one of the most powerful features of
C++.
2.1. Justification
2.1.1. Type Safety
Stdio is not type safe, which is one of the reasons you are using C++, right? IO stream is type safe.
2.1.2. Standard Interface
When you want to dump an object to a stream there is a standard way of doing it: the <<>(e)
Casts away the const−nessof objects, variables or pointers. It gives an error when the types differ
more than in const and volatile modifiers.


Don’t use this to cast away const−nessof objects that were originally defined as being const and on
which non−constoperations are being executed. Doing this, results in undefined behaviour.
You typically use this when you need to access an API that incorrectly defines a function signature.
When you are 100% sure that the function you want to call doesn’t perform non−constoperations
on the argument, you can safely cast away the const−nessof the argument that was initially defined
as being const.
Example 6.2: const_cast Example
int countChars(char *pString, char character);
const char *p_somestring = "Let’s make things better";
int result = countChars(const_cast(p_somestring), ’e’);
4.2. dynamic_cast(e)
Makes it possible to safely downcast pointers and references to base classes. It thus returns the
appropriate sub−objectin the hierarchy chain. It returns 0 if this cast wasn’t possible on pointers
and throws the bad_cast exception if the cast wasn’t possible on references. This effectively says
"convert this Object into a Penguin or give me 0 if its not an Penguin,". This provides dynamic
typing, you don’t know what will happen until run−time.
Example 6.3: dynamic_cast Example
class B { /* at least one virtual function */ };
class D : public B { /* ... */ };
B *p_b1 = new B;
B *p_b2 = new D;
D *p_d1 = dynamic_cast(p_b1); /* will be 0 */
D *p_d2 = dynamic_cast(p_b2); /* will be an object of type D*/
4.3. reinterprete_cast(e)
This type of casts treats pointers and references as incomplete types. Using the
reinterprete_cast yields values that are typically not guaranteed to be usable without casting
back to their original types. It’s difficult to say more about this kind of casts since their applicability
is very implementation dependent.
Example 6.4: reinterprete_cast Example
void someFunction(char *p_string) { *p_string = ’x’; }
typedef void (*FPType)(const char*);
FPType p_function_pointer = reinterprete_cast(&someFunction);
/* calling someFunction through p_function_pointer is not guaranteed to work */


4.4. static_cast(e)
This is very similar to the old C−stylecasts. Only use it when none of the above seem to fit the bill.
It will only succeed if there’s an implicit conversion possible either from T to the type of e, or from
the type of e to T.
Example 6.5: static_cast Example
Fraction fraction(1,2);
double d = static_cast(fraction);

Chapter 7
Best practices
1. Commenting Out Large Code Blocks
Sometimes large blocks of code need to be commented out for testing. You can’t use /**/ style
comments because these can’t be nested. Surely a large block of your code will contain at least
one comment, won’t it?
1.1. Use #if 0
The easiest way to do this is with an #if 0 block. Don’t use #ifdef as someone can unknowingly
trigger ifdefs from the compiler command line.
Example 7.1: Commenting Out Large Code Blocks Example
void example()
{
great looking code
#if 0
lots of code
/* a comment */
some more code
#endif
more code
}
1.2. Use Descriptive Macro Names Instead of 0
The problem with #if 0 is that a while later neither you nor someone else has any idea why this
code has been commented out. Is it because a feature has been dropped? Is it because it was
buggy? Didn’t it compile? Can it be reinstated? It’s a mystery.
Therefor you can also chose to use descriptive macro names instead of #if 0.
Example 7.2: Commenting With Descriptive Macro Names
void example()
{
great looking code
#if NOT_YET_IMPLEMENTED
travel_through_air();

#endif
a bit of code
#if OBSOLETE
/* a comment */
travel_by_foot();
#endif
#if TEMP_DISABLED_OUT_OF_GAS
travel_by_car();
#endif
}
2. Prefer positive boolean comparisons
It’s much easier to think in a positive way about a situation than to be presented with the negative
alternative and having to transform it in your mind by yourself to positive. People tend to have a
’logical’ or ’the default behaviour’ feeling about true, which makes it easy to think about. On the
contrary, false is mostly regarded is the ’exception’, ’the error situation’ or the ’alternative way out’.
Therefor we prefer constructs like this:
Example 7.3: Positive boolean comparison, the right way
setup();
if(something == true)
{
dowork();
}
cleanup();
return;
above the following negative counterpart :
Example 7.4: Positive boolean comparison, the wrong way
setup();
if(something == false)
{
cleanup();
return;
}
dowork();
cleanup();
return;
3. Handle cleanup situations with boolean indicators

Often you’re presented with the problem that your code logic contains a series of initializations that
can all potentially fail. Typically you want to interrupt any further execution, cleanup and return an
error message. Such situations have been known to be resolved through the use of exceptions,
gotos, large if−then−elseconstructs and boolean indicators. From these options, it’s the last one we
prefer.
Below is an example of such a typical code cleanup situation :
Example 7.5: Cleanup with boolean indicators
void some_function()
{
bool file_setup = false;
bool dir_setup = false;
/* try to create a new file object and open it for reading */
QFile *p_file = new QFile("/path/to/file");
if(p_file != 0 &&
p_file−>open(IO_ReadOnly) == true)
{
file_setup = true;
}
QString dir_path("/path/to/default/dir");
if(file_setup == true)
{
/* if the file was setup, read its contents and use it for */
/* further processing */
QTextStream textstream(p_file);
QString dir_path = textstream.readLine();
dir_path = textstream.readLine();
}
/* try to create a new dir object and open it for reading */
QDir *p_dir = new QDir(dir_path);
/* some vars that are needed by the dir logic */
if(p_dir != 0 &&
p_dir−>exists() == 0)
{
/* do stuff with the dir */
dir_setup = true;
}
else
{
cout << dir_setup ="=" file_setup ="=">close();

}
delete p_dir;
delete p_file;
}
3.1. Justification
− You prevent unnecessary consecutive indentations as is the case with large if−then−else
constructs.
− You don’t have the maintaince hassle of local gotos which could point anywhere and present
a number of difficult to solve C++ issues such as accessing object whose initializations has
been jumped over.
− It’s very easy and clear to follow the logical flow, no jumps are executed as with gotos and
exceptions.
− You can perform context−sensitive cleanups that combine the states of several boolean
indicators.
4. Learn about enum classes
In a lot of cases regular enumerations suffice to define a group of valid integer constants as a
distinct type. A typical example follows :
Example 7.6: Classic enumeration example
typedef enum
{
ALPHA = −4, /* this maps to the "alpha" string in the code */
BETA = −3, /* this maps to the "beta" string in the code */
PRE = −2, /* this maps to the "pre" string in the code */
RC = −1, /* this maps to the "rc" string in the code */
NONE = 0, /* this maps to no string (or all the invalid strings) */
P = 1 /* this maps to the "p" string in the code */
} SuffixType;
This approach however presents a number of drawbacks :
− The values are limited to integers.
− It’s not possible to evolve the constants in time to provide for example custom output
methods, alternative synonimous values (strings for example), conversion from and to other
types, and so on ...
− Casting between integers and enums is very error prone, you could cast a value that’s not
available in the enum.
Therefore it’s often justified to write enum classes. These classes contain private constructors and
initialize constant instances of themselves as static class variables.
An advanced implementation example follows :
Example 7.7: Enumeration Classes Example

/*
* This creates a collection of the possible suffix type instances and
* neatly maintains the textual and numerical representation together.
* No additional instance can be created through the public interface.
* The instances are registered in an internal dictionary which makes it
* very easy to retrieve the exact object that corresponds to a textual
* representation.
* The type of the enum values is a pair, composed out of a string and a
* matching integer.
*/
class SuffixType : public QPair
{
public:
/**
* The enumeration’s values
*/
static const SuffixType ALPHA;
static const SuffixType BETA;
static const SuffixType PRE;
static const SuffixType RC;
static const SuffixType NONE;
static const SuffixType P;
/**
* Retrieve a SuffixType object instance according to its textual
* representation.
**
@param string The string to look up.
* @return A SuffixType that correponds to the provided string, or
* SuffixType::NONE if no match was found.
*/
static const SuffixType &get(QString string);
/**
* Outputs the textual representation to an output stream.
*/
friend std::ostream &::operator<<(std::ostream &rStream, const SuffixType &rSuffixType); private: /** * Private constructor that will only be called during the initialization * of the static class variables. */ SuffixType(QString string, int value); /** * Class wide collection that maps string representations of class * instances to the instances themselves. */ static QDict *mpMap;
};
/* Define and initialize the enumeration values. */
const SuffixType SuffixType::ALPHA("alpha", −4);
const SuffixType SuffixType::BETA("beta", −3);
const SuffixType SuffixType::PRE("pre", −2);
const SuffixType SuffixType::RC("rc", −1);
const SuffixType SuffixType::NONE("none", 0);
const SuffixType SuffixType::P("p", 1);
/* Define the static class−wide dictionary */

C++ Coding Standard Part 2-2

Example 5.7: Class Declaration Template

#ifndef XX_h
#define XX_h
// SYSTEM INCLUDES
//
// PROJECT INCLUDES
//
// FORWARD REFERENCES
//
namespace NN
{
/**
* A detailed description of the class.
**
@brief A short description of the class
* @author Name of the author
* @version version
*/
class XX
{
public:
/// @name Lifecyle
//@{
// LIFECYCLE
/**
* Default constructor.
*/
XX();
/**
* Copy constructor.
**
@param from The value to copy to this object.
*/
XX(const XX &from);
/**
* Destructor.
*/
~XX();
//@}
// OPERATORS
/**
* Assignment operator.
**
@param from the value to assign to this object.
**
@return A reference to this object.


XX &operator=(XX &amp;amp;amp;amp;from);
// OPERATIONS
/// @name Accessors
//@{
// ACCESS
//@}
/// @name Inquiries
//@{
// INQUIRY
//@}
protected:
/**
* An odd static method
*/
static void oddStaticMethod();
/**
* An odd inline method
*/
void oddInlineMethod();
/**
* An odd static and inline method
*/
static void oddStaticInlineMethod();
private:
// MEMBER VARIABLES
static int mInstances;
};
// INLINE METHODS
#include
}
// EXTERNAL REFERENCES
//
#endif // XX_h
5. Class Implementation

A common class implementation layout is critical from a code comprehension point of view. Static
member variables initialization and static methods must come first because the static keyword is
forbidden in class implementation.
Following is the template that should be used to organize each class implementation.
Example 5.8: Class Implementation Template
// STATIC MEMBER VARIABLES INITIALIZATION
int XX::mInstances = 0;
// STATIC METHODS
void XX::oddStaticMethod()
{
// implementation
}
// NON STATIC METHODS
XX::XX()
{
instances++;
// implementation
}
XX::XX(const XX &from)
{
instances++;
// implementation
}
XX::~XX()
{
instances−−;
// implementation
}
XX &XX::operator=(XX &from)
{
// implementation
}
6. Class Inline Methods Implementation
A common class inline methods implementation layout is critical from a code comprehension point

of view. Static methods must come first because the static keyword is forbidden in inline methods
implementation.
Following is the template that should be used to organize each class inline methods
implementation.
Example 5.9: Class Inline Methods Implementation Template
#ifndef XX_inline_h
#define XX_inline_h
// STATIC METHODS
inline void XX::oddStaticInlineMethod()
{
// implementation
}
// NON STATIC METHODS
inline void XX::oddInlineMethod()
{
// implementation
}
#endif // XX_inline_h

C++ Coding Standard Part 2-1

Part II
Code Formatting


Chapter 3
Braces and parenthesis
1. Braces Policy
Place braces under and inline with keywords, like this :
Example 3.1: Braces Policy Example
if(condition) while(condition)
{ {
... ...
} }
1.1. Justification
− If you use an editor (such as vi) that supports brace matching, this is a much better style than
the default unix style where braces aren’t vertically aligned. Why? Let’s say you have a large
block of code and want to know where the block ends. You move to the first brace hit a key
and the editor finds the matching brace.
Example 3.2: Braces Policy Justification
if(very_long_condition && second_very_long_condition)
{
...
}
else if(...)
{
...
}
To move from block to block you just need to use cursor down and your brace matching key. No
need to move to the end of the line to match a brace then jerk back and forth.
2. Braces Usage
All if, while and do statements must either have braces or be on a single line.
Always Uses Braces Form, even if there is only a single statement within the braces.
2.1. Justification
− Easier to read, you just have to scan for one form.
− Uniform idiom for scope blocks since they are all enclosed in braces.
− It provides a more consistent look.
− This doesn’t affect execution speed and it’s easy to apply.
− It ensures that when someone adds a line of code later there are already braces and they
don’t forget.
Example 3.3: Brace Usage Example
if(somevalue == 1)
{
somevalue = 2;
}
3. Parenthesis Policy
− Do put parens next to keywords.
− Do put parens next to function names.
− Do not use parens in return statements when it’s not necessary.
Example 3.4: Parenthesis Policy Example
if(condition)
{}
while(condition)
{}
strcpy(s, s1);
return 1;

Chapter 4
Class Design
1. Required Class Methods
To be good citizens almost all classes should implement the following methods. If you don’t have to
define and implement any of the "required" methods they should still be represented in your class
definition as comments. If you just let the compiler generate them without indicating through
comments that you know that this is the intended behaviour, people might wonder about the
possibility of an omission or oversight.
1.1. Details
1.1.1. Default Constructor
If your class needs a constructor, make sure to provide one. You need one if during the operation
of the class it creates something or does something that needs to be undone when the object dies.
This includes creating memory, opening file descriptors, opening transactions etc.
If the default constructor is sufficient add a comment indicating that the compiler−generatedversion
will be used.
If your default constructor has one or more optional arguments, add a comment indicating that it
still functions as the default constructor.
1.1.2. Virtual Destructor
If your class is intended to be derived from by other classes then make the destructor virtual. You
should always make a destructor virtual for the sake of future extensibility. Only make it non virtual
if you’ve got a real good reason to do so.
1.1.3. Copy Constructor
If your class is copyable, either define a copy constructor and assignment operator or add a
comment indicating that the compiler−generatedversions will be used.
If your class objects should not be copied, make the copy constructor and assignment operator
private and don’t define bodies for them. If you don’t know whether the class objects should be
copyable, then assume not until the copy operations are needed.
1.1.4. Assignment Operator
If your class is assignable, either define a assignment operator or add a comment indicating that
the compiler−generatedversions will be used.
If your objects should not be assigned, make the assignment operator private and don’t define
bodies for them. If you don’t know whether the class objects should be assignable, then assume
not.
1.2. Justification
Virtual destructors ensure objects will be completely destructed regardless of inheritance depth.
You don’t have to use a virtual destructor when:
− You don’t expect a class to have descendants.
− The overhead of virtualness would be too much.
− An object must have a certain data layout and size.
A default constructor allows an object to be used in an array.
The copy constructor and assignment operator ensure an object is always properly constructed.
Making them private, prevents copies from objects being made without you knowing about it and
thus possibly inducing an unnecessary overhead or cause for inconsistency.
Example 4.1: Required Class Methods Example
class Planet
{
public:
// Planet();
Planet(int radius= 5);
~Planet();
private:
Planet(const Planet &);
Planet &operator=(const Planet &amp;amp;amp;amp;amp;amp;);
};
2. Initialize all Variables
You shall always initialize variables. Always. Every time.
2.1. Justification
− More problems than you can imagine are eventually traced back to a pointer or variable that
was left uninitialized. C++ tends to encourage this behaviour by propagating the initialization
to the constructors of the parent classes.
3. Accessor Styles
Accessor methods provide access to the attibutes of an object. Accessing an object’s attributes
directly, as is commonly done in C structures, is greatly discouraged in C++. It exposes
implementation details of the object and degrades encapsulation. There are two accepted ways to implement accessors, the preferable way is the following :
3.1. Attributes as objects
Example 4.2: Attributes as object accessor style
class X
{
public:
const String &name() const { return mName; }
String &rName() { return mName; }
private:
String mName;
}
The main weakness of this approach is that when returning a reference to basic types (as in the
rAge() method), it’s impossible to perform checks on the provided value. To solve this, you can
either create a wrapper class or resort to the second accessor implementation style. The preferred
method is of course, in this example, to create an Age class which contains all consistancy checks
as class methods or statements in its constructor.
The advantage of this approach is that it’s more consistent with OOP : the object should do it. An
object’s assignment (=) operator can do all the checks for assignments. This centralizes the
consistancy checks in one place, in the class, where it belongs.
When possible, use this approach instead of the "One method name" accessor style.
3.2. One method name
Example 4.3: One method name accessor style
class X
{
public:
int age() const { return mAge; }
void age(int age) { mAge = age; }
private:
int mAge;
}
Using this approach, it’s possible to include some checks about the value provided to the age()
method. However these checks make only sense when handling basic types since objects should
perform their checks internally. Failing to do so would mean that every accessor has to
reimplement these consistancy rules over and over again.
The huge drawback here is that objects aren’t treated in their own right and that encapsulation
somewhat fails. It is better to rely on the object’s assignment operator.
When possible, use this approach only for base types members (int, float, long, etc...).

Chapter 5
Class and file organization

1. Class Files
− Each class definition should be in its own file where each file is named directly after the
class’s name.
− Source files have the .cpp extension and header files have the .h extension.
− In general each class should be implemented in one source file. A common exception to this
rule are inner classes that provide class specific functionality such as thread execution.
Another common exception are very closely related classes such as a collection class and its
iterator.
− If the source file gets too large or you want to avoid compiling templates all the time then add
additional files, where the section is lower case and seperated of the classname through an
underscore.
− If the class uses inline methods, their implementation are in a separate header suffixed by
’_inline’.
1.1. Justification
− Using exactly the same name as the real class makes it easy to establish the relation.
− Not implementing several classes in one source file makes it very easy to find a class
implementation when looking for it.
Example 5.1: Class Files Example
ClassName.h
ClassName_inline.h
ClassName.cpp
ClassName_section1.cpp
ClassName_section2.cpp
2. File Header
A common file header for the whole project is important from a legal point of view and quickly find
file version.
Following is the template that should be used to organize each file header for a project using the
GPL.
Example 5.2: File header for a project using the GPL
/*

* $Id$
***
[Project Name]
**
Copyright (C) 2001,2002 [Main developers names]
* IPSquad
**
This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
**
This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
**
You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
3. Class Documentation
For the creation of developer API documentation we’re using Doxygen. Since we sometime use Qt
it’s a great asset that a documentation tool understands the concept of Qt’s meta object system,
slots and signals.
Doxygen is very much likely to javadoc, but then for C++, and more powerful.
A documentation comment is a C comment that immediately precedes a class, method, constant or
property declaration. It takes the following form:
Example 5.3: Documentation Comment Example
/**
* Documentation goes here
*/
class MyClass
{
...
The double asterisk at the start of the comment differentiates a documentation comment from a
normal comment. To make the documentation comment blocks clearly stand out, each line can be
preceded by asterisks which will be ignored when the output is generated.
The documentation is a mixture of :
3.1. Normal text
Paragraphs must be separated by at least one blank line.

3.2. Code fragments
Inline code fragments have to take the following form :
Example 5.4: Documentation inlined code fragment example
@code
.....code fragments....
@endcode
3.3. Various Doxygen tags
The tags that Doxygen understand are all in the following form and should be entered on one line :
Example 5.5: The form of Doxygen tags
@tagname [tag parameters]
3.4. List of Doxygen valid tags
The valid Doxygen tags for each type of source code entity are :
Tag Description
@brief [one_sentence] A short description of the class.
@author [one_sentence] The class’s author.
@version [once_sentence]
The class’s version. This can for example be
set to the RCS/CVS tags $Id:
cpp_codingstandard.xml,v 1.3
2002/10/07 04:57:58 ervin Exp $ or
$Revision: 1.3 $.
@return [one_sentence] A sentence describing the return value.
@exception [exception_name]
[exception_description]
Describe an exception that could be thrown by
this method.
@param [param_name]
[param_description] Describe a parameter.
3.5. Grouping members
If a class has many members, it is often desired to group them together. Doxygen already

automatically groups things together on type and protection level, but maybe you feel that this is
not enough or that that default grouping is wrong. For instance, because you feel that members of
different (syntactic) types belong to the same (semantic) group.
A member group is defined by a
//@{
...
//@}
block. Note that the members of the group should be physically inside the member group’s body.
Before the opening marker of a block a separate comment block may be placed. This block should
contain the @name command and is used to specify the header of the group. Optionally, the
comment block may also contain more detailed information about the group.
Example 5.6: Class with groups
/** A class. Details */
class Test
{
public:
/// @name First group
//@{
void func1InGroup1();
void func2InGroup1();
//@}
/** Function without group. Details. */
void ungroupedFunction();
protected:
/// @name Second group
//@{
void func1InGroup2();
void func2InGroup2();
//@}
};
4. Class Declaration
A common class declaration layout is critical from a code comprehension point of view and for
automatically generating documentation. C++ programmers, through a new set of tools, can enjoy
the same level generated documentation Java programmers take for granted.
Following is the template that should be used to organize each class declaration.

C++ Coding Standard Part 1

Part I
Make Names Fit



Chapter 1
Selecting names
A name is the result of a long deep thought process about the ecology it lives in. Only a
programmer who understands the system as a whole can create a name that "fits" with the system.
If the name is appropriate everything fits together naturally, relationships are clear, meaning is
derivable, and reasoning from common human expectations works as expected.
If you find all your names could be Thing and DoIt then you should probably revisit your design.
1. Class Names
− Name the class after what it is. If you can’t think of what it is that is a clue you have not
thought through the design well enough.
− Compound names of over three words are a clue your design may be confusing various
entities in your system. Revisit your design.
− Avoid the temptation of bringing the name of the class a class derives from into the derived
class’s name. A class should stand on its own. It doesn’t matter what it derives from.
− Suffixes are sometimes helpful. For example, if your system uses agents then naming
something DownloadAgent conveys real information.
2. Method and Function Names
Usually every method and function performs an action, so the name should make clear what it
does : checkForErrors() instead of errorCheck(), dumpDataToFile() instead of
dataFile(). This will also make functions and data objects more distinguishable. Classes are
often nouns. By making function names verbs and following other naming conventions programs
can be read more naturally.
Suffixes are sometimes useful :
− Max −to mean the maximum value something can have.
− Cnt −the current count of a running count variable.
− Key −key value.
For example : retryMax to mean the maximum number of retries, retryCnt to mean the current
retry count.
Prefixes are sometimes useful :
− is − to ask a question about something. Whenever someone sees Is they will know it’s a
question.
− get −get a value.
− set −set a value.
For example : isHitRetryLimit.

3. Variable Names
Make every variable name descriptive, limit the use of abbreviations or letter−words. It’s worth
writing words completely since it makes the code much more readable. Beware however that when
trying to find a good name, you don’t end up with with something like
’the_variable_for_the_loop’, use a proper English word for it like ’counter’ or ’iterator’.
English is a rich language and trying to find a correctly fitting word is important for code brevety,
cleanness and variation. Whenever in doubt, just use a thesaurus like Merriam−Webster
(http://www.m−w.com) or a rhyming dictionary like Rhyme
(http://rhyme.sourceforge.net/).
3.1. Exceptions
Some standard variables are used for often recurring tasks. Below is a list of those that are
accepted :
− i : integer counter
− it : STL−likeiterator
_it : STL−likeiterator of a certain type for differentiation amongst types
− tmp_ : eg. tmp_qstring, tmp_int, tmp_float for variables that are solely used
for the storage of temporary intermediate values
4. No All Upper Case Abbreviations
When confronted with a situation where you could use an all upper case abbreviation instead use
an initial upper case letter followed by all lower case letters. No matter what.
4.1. Justification
People seem to have very different intuitions when making names containing abbreviations. It’s
best to settle on one strategy so the names are absolutely predictable.
Take for example NetworkABCKey. Notice how the C from ABC and K from key are confused.
Some people don’t mind this and others just hate it so you’ll find different policies in different code
so you never know what to call something.


Chapter 2
Naming scheme
A standard naming scheme is important to ensure that all code looks similar and that every
developer can understand new code immediately without have to grasp a new naming scheme
first.
One of the main aspects of this naming scheme is that all names should contain key information
about the type of language construct is refers to. Additionally, certain prefixes will be used to
prevent common error in the use of basic C++ concepts such as pointers, references and scope.
This however doesn’t involve into a full−blownand difficult to understand and maintain Hongarian
notation.
1. Class Names
− Use upper case letters as word separators, lower case for the rest of a word
− First character in a name is upper case
− No underbars (’_’)
1.1. Justification
− Standard naming scheme in very clean OO languages such as Java.
− Stands out the best amongst the other names formatting, since a class is the basic element in
C++ this is a great benefit.
Example 2.1: Class Names Example
class NameOneTwo
class Name
2. Method Names
− Use upper case letters as word separators, lower case for the rest of a word
− First character in a name is lower case
− No underbars (’_’)
2.1. Justification
− Differentiates the first word part, which is often a verb. This makes it very clear what a method
does.
− Not exactly similar to class names and thus makes Class.doSomething() much more
readable as Class.DoSomething(), cleanly indicating through case which is which.
Example 2.2: Method Names Example

class NameOneTwo
{
public:
int doIt();
void handleError();
}
3. Class Member Names
− Member names should be prepended with the character ’m’.
− Member the ’m’ use the same rules as for class names.
− ’m’ always precedes other name modifiers like ’p’ for pointer.
3.1. Justification
− Prepending ’m’ prevents any conflict with method names. Often your methods and attribute
names will be similar, especially for accessors.
Example 2.3: Class Member Names Example
class NameOneTwo
{
public:
int varAbc();
int errorNumber();
private:
int mVarAbc;
int mErrorNumber;
String *mpName;
}
4. Method Argument Names
− The first character should be lower case.
− All word beginnings after the first letter should be upper case as with class names.
4.1. Justification
− You can always tell which variables are passed in variables.
− You can use names similar to class names without conflicting with class names.
Example 2.4: Method Argument Names Example
class NameOneTwo
{
public:
int startYourEngines(Engine &rSomeEngine, bool autoRestart);

}