My C++ Coding Style




 

Introduction


Before I embark onto describing my coding style which I have picked up from a few practical as well as theoretical sources, it might just be a good idea to analyze if C++ is really for you. In essence the difference between C++ and C is more theoretical than practical. If you are beginning to program in any OOPs language then you have to think in OOPs way otherwise there is no real advantage. Simply using a C++ compiler to compile a C program wouldn't really help. Though some die hard C++ fans would counter me, I feel that C++ is only needed if you are actually building some software which needs to last over generations. Effectively which means that it would be used by a number of people in its entire life span as well as it would be modified by those same very people. This brings us to the two core issues of software engineering. Manageability and efficiency, while C++ is far more manageable, C is much more efficient. However if you are only interested in writing software for some small student assignments then may be you would be better off using a simple and far more efficient (even efficiently written programs in c++ are anywhere between 60% to ?? slower than C ones) language like C. Also if all that you are interested in is a quick and simple solution may be looking at Perl or python would help. The main bottleneck in programing in any language supporting OOPs is developing the thought process, wherein you are actually thinking as per the OOPs model and not just converting and collecting your functions in classes. If you are new to OOPs and are just beginning to use C++, I suggest that you rather start with Java. The reason is that Java leaves behind efficiency and concentrates just on portability, which makes the OOPs model explicit. In a way Java forces you to think in OOPs whereas C++ still has back doors wherein you can bypass the OOPs model.

In this article I present a set of coding conventions which we have been following for some time now and have found to be pretty effective. These have been picked up from a variety of sources. However this is in no way the defacto coding standard and there may be a lot of loop holes. The only defense which I have at the moment is that we have been practising these and have found them to be effective.

Coding Style


  • The first and foremost convention is regarding nomenclature. We follow the following, class names start with a capital letter, function names start with a small letter and capitalization may be used to break word, underscores are not used. If you are building a library, prefix the name of that library in all the class names. This would save name conflicts to a large extent.
     
  • Files are named separated by underscores. The names itself is derived from the class contained in that file. In order to keep the file name itself small, common prefix can be removed from all the files. C++ header file names end in .hh and C header file names in .h. For the C++ source files, a .C may be used though we use .cc. So, for example, a file containing the class, AssetSimuProcessConstructor can be put in the file simu_proc_constr.hh.
     
  • Constructors are declared together in one public section, next other public functions in another public declaration, then private functions and finally private variables and classes. Separate interface functions and other common functions by various public declarations.
     
  • Parenthesis are written separated by spaces as mySmartPrint( stderr, "Test\n" ); and comma is written attached to the left variable.
     
  • Variable names use underscores to break words and never capitalization. Also, follow the golden rule of keeping name of the variable small.
     
  • Header files never include other header files. The dependencies are sorted out in the source files. This helps prevent multiple inclusions as well as makes the dependencies clearer for someone who is looking at your code for the first time.
     
  • We follow the following style for include files, first put all C++ standard includes, then put any ?C? standard includes, next any common local includes. All the defines should follow any includes, until the includes themselves need these defines. It is also a good practice to group all the defines together in one file.
     
  • It is always a nice idea to make one class the base of all others containing just the id (name or something more). This is useful for many things (e.g. debugging).
     
  • Define one simple DEBUG macro and use this to print your debugging information. The macro itself contains debug levels and also echoes the id of the base class, to clarify which object this message is coming from. If you later want to distribute your software for some professional purpose may be these macros could be stripped off. This has the advantage that at any given time debugging is built into your software.
     
  • Static functions are always a bad practice like global vars until there is some really good reason for using them.
     
  • Make classes of concepts not functionality, remember objects are meant to hold data and functions together not just to group common functions.
     
  • If you expect some constraint to be satisfied for the correct execution of your code put an assertion. Also make liberal use of const, this provides the compiler with an opportunity to optimize the code more aggressively along with helping save some common programing errors.
     
  • If you need to get some parameters from the user on command line, use getopts instead of writing the parsing function your self. This makes the implementation neat as well as saves you a lot of unnecessary error checking.
     
  • Whenever you want to force a design decision, abstract out the interface using abstract classes, with all functions as pure virtual. This will make the code maintainable across many generations.
     
  • Automatic documentation tools like Doxygen, do a great job without too much effort on your part. They also help someone browsing through your code get an overall idea of the software. So, it is generally a good practice to use them. Whenever putting comments, try to follow the style which the particular tool understands (e.g. /** .. */) for Doxygen.
     
  • Always discuss the top level class hierarchy with someone good in OOPs, before proceeding to implementation. The clearer you are before starting implementation of your ideas in C++, the simpler your code would turn out to be.
     
  • C++ is slower but more manageable than C. Until you have people who really understand what they are coding and the reasons behind future and past design decisions use C++ for any large sized project. This will help keep the goofups at a maintainable level.
     
  • Use a versioning system if you are working with someone else. CVS is real good. Also when using cvs put the first line as $Header$ in comments (# or //), this really helps.
     
  • Write comments to illustrate the ideas behind what you are doing, not how you are doing. How you are doing something is clearly established from your code. The ideas make reading the code lot more pleasurable and clear. Comments like *}//End of loop. are junk, even an idiot can see that.
     
  • If you need some variable just for loop iteration declare it inside the for statement. However, try to declare all your other variables at the top this will make understanding the code easier as well as make it more maintainable.
     
  • Donot use C style calloc and malloc in C++, the operators new and delete are better.
     
  • It is always more manageable to use class pointers rather than variables. Use new to create and delete to delete objects.
     
  • Keep the size of private classes small. In case your private classes are growing large you perhaps need to relook at your design. Donot create separate files for private classes. Define their functions along with their base class.
     
  • Use iterators they save you a lot of type casts along with many other benefits.
     
  • Use template classes only if you need them. They complicate simple things. Generally unless you are making generic libraries they are not for you.
     
  • It is generally a good idea to define a constructor which can take the object of the class type itself as an argument.
     
  • Finally the golden rule, "Try not to do C programming in C++".

Conclusion


There is no substitute to practice -:)!
 
 
 

Last Updated May 14, 2021 © Anup Gangwar, Department of CSE, IIT Delhi
CSE Valid HTML 4.0! Valid CSS!