Vous êtes sur la page 1sur 10

C++ Programming Best Practices

11/30/2009

Hi-Tech SAMIR DILIP YADAV samir.yadav@tcs.com

Friend Function

This feature was included in C++ to ease transition from structured programming to object oriented programming. It is not a true OOP feature. It is not universally found in all OOP languages. Hence we should not use this feature. If used it becomes very difficult to convert the code to some other OOP language. Eg. If friend functions are used then it becomes messy to convert C++ code to Java.

Multiple Inheritance

Multiple inheritance is not universally supported by all OOP languages. Moreover use of multiple inheritance can lead us up to a classical problem. Eg. Class B and C inherit from A. Class D inherits from B and C. Class A, B and C have a common method named x(). Then whose x() should D inherit? From B or C? We would not want to encounter this classical problem when we are coding. Hence we should avoid using multiple inheritance when we design class hierarchy.

External Variables

External variables are not required by OOP languages. In fact external variables are against OOP paradigm. This feature is included in C++ merely to maintain backward compatibility with C. Use of external variables should be curbed through good class design.

Inline Functions

If a function contains very few lines of code, then we can make it inline and we should make it inline. This will increase efficiency of our code to some extent. If we mistakenly use inline keyword for a larger function then compiler simply ignores the request. Hence it is absolutely safe to use inline freely.

#define vs const

Preprocessor directive #define as well as const keyword can be used to define a constant variable. However const keyword method should be preferred over #define one. #define is C style way of doing things and we discourage its use in C++. When you do a #define you cannot specify the data type of the constant when can lead to bugs.

struct vs class

Class concept renders structures obsolete. Everything that can be done using structures can be done using class as well. Again this feature is used to maintain mere compatibility with C. We should prefer use of class over a structure.

goto

goto is a remnant of very old programming languages. Modern languages have more sophisticated and continent alternatives to goto. Using goto in your code lands you into the classical mess called code spaghetti. Every logic written using goto can be rewritten using other looping constructs. Hence we should never use this construct.

Function Declaration

In function declaration it is optional to include the names of variables passed to the function. Still for sake of clarity it is a very good idea to include names in declaration.

Eg. void display_point( int x , int y )

Although below form is equivalent to above one, its use should be avoided. void display_point( int , int )

Operator Overloading

Operator overloading is a very exciting feature. Yet it should be used with extreme care. When an operator is overloaded the new functionality associated with it should be in some ways similar to original functionality. If some bizarre meaning is associated with an operator then the code becomes very hard to comprehend for others.

Eg. Original meaning of + is to add two numbers. If required by program logic then we can associate extra functionality with + to add two objects. This goes in well. However + should not be used for something unthinkable like subtracting two numbers (Yes! You can do almost anything with operators when you overload them).

Naming
Commonly used names for loop counter variable like i and c should only be used. In some programming languages it is mandatory to use these letters only for loop counter variables.

All names should adequately describe its purpose. Eg. Names like abal does not describe its purpose adequately whereas account_balance does. Doing so ensures that other people reading your code dont have to scratch their heads to understand your shorthands.

Variable/function names should be all lowercase. Underscore is used as a separator between parts of name.

Names of constants should be all in uppercase. Again underscore is used as a separator between parts of the name.

Indentation
Three letter indentation should be used everywhere in code. Block of code is a sequence of statements delimited by braces {}. Wherever a block of code is used, the code inside should be indented three spaces to the right. This should be followed for code inside method, class, loop, if clause etc. The delimiting braces should be placed exactly below one another. By using indentation blocks of code within the program can be easily and effortlessly identified. Hence readability receives a boost.

Eg. int area_of_rectangle( int length , int breadth ) { return( length * breadth ) ; }

Avoid following usage although equivalent to above one. int area_of_rectangle( int length , int breadth ) { return( length * breadth ) ; }

Eg. if( length < 0 ) { cout << Error ; } else { cout << length * breadth ; } Avoid following usage although equivalent to above if ( length < 0 ) { cout << Error ; } else { cout << length * breadth ; }

Logical decisions

When making logical decision, constant values should be placed to the left.

Eg. if( 24 == x )

{ // Do this. }

Avoid following usage although equivalent to above if( x == 24 ) { // Do this. }

This is because one may forget to add the double equal to sign. The compiler will give no error. But there will be a catastrophic failure in logic. if( x = 24 ) // Compiler will not give error because x = 24 is assignment and perfectly ok. { // Do this. }

But in following case compiler immediately throws an error because you cannot assign a variable to a constant. if( 24 = x ) { // Do this. }

loop, if
Sometimes body of a if clause or a loop may contain single line of code. In such a case the language permits us to omit delimiting curly braces. Still it is regarded as best practice to explicitly include curly braces.

Eg. for( int i=0 ; i<10 ; ++i ) { cout << Hello world << endl ; }

Avoid following usage although equivalent to above for( int i=0 ; i<10 ; ++i ) cout << Hello world << endl ;

Functions

It is a excellent practice to place return statement at the end of a function even though it may not return any value. This practice contributes to logical clarity.

Recursion

Criticism for using recursion is Recursive code is memory hungry. Consumes lot of CPU time.

But now a days memory is abundant and CPSs are getting faster day by day. Hence these disadvantages of using recursion are neutralized. However on the plus side of recursion Recursive code is smaller. Logically more clear. Very easy to comprehend.

Everything that can be done using iteration can be done using recursion. Hence, wherever possible recursive logic should be preferred over iterative one.

References

Object Oriented Programming in C++ -Robert Lafore

Vous aimerez peut-être aussi