C++ Programming Tips

Apart from having the discipline to always do things properly, these are the top 10 principles and concepts I think anyone who wants to be a truly excellent C++ programmer should adhere to and use:

  1. Object Orientated Designs
  2. Design Patterns
  3. Standard Libraries
  4. Templates
  5. Descriptive Names
  6. Const Correctness
  7. Values, References and Pointers
  8. Namespaces
  9. Embedded Documentation
  10. Avoid Macros

1. Object Orientated Designs

Object orientation has been around for so long it’s probably due for an upgrade.

Even so, many C++ systems still do not make use of the true power, re-usability and simplicity that a good object orientated design gives.

If you want to code in C++, but you don’t understand object orientation properly, please either skill up on the subject immediately, or do me a favor and stay away from programming.

As a contractor, I may just end up having to work on your code somewhere down the line. Rather become a truck driver. Or yoga instructor. Or something like that.

2. Design Patterns

Design Patterns are worth learning, no matter what language you program in. Design patterns are standard ways of doing things.

If you understand a pattern, it is easy to understand any code that uses it.

The design pattens I use most are:

3. Standard Libraries

When there is a standard library available, don’t create your own.

When I was younger I did not follow this advice and I suffered greatly for it.

Other people weren’t familiar with my libraries, so I wasted oodles of time to skill them up. Apart from the wasted time, I probably also lost half my hair because of the multitudes of problems I faced with cross platform compilation and the reworks that were necessary each time each time a compiler upgrade was released.

If you want to be a good C++ programmer, the most important libraries to learn and use are:

4. Templates

Template programming is probably the coolest thing invented this century. After regular expressions. And Velcro. And cable-ties. Anyways.

Templates are simply great for implementing functions and constructs that can be applied to various data types. This is especially useful if you want to use the same classes and/or functions on types that don’t inherit from a common base class.

If you don’t know how to use templates yet, spend one day to learn it, and save yourself a hundred days worth of effort later in your programming career.

5. Descriptive Names

Yet another curse that comes from the C-style way of doing things, is the tendency by C++ programmers to use heavily abbreviated and super-short class, function and variable names.

Drives me crazy.

It seems that some people still think we live in a world where programming is done in terminals that have 80 or less characters available per line, and that we absolutely have to try and make lines as short as possible.

If you are one of these programmers, wake up and smell the coffee. Screens are big now and have high resolutions.

And if you’re fretting about all the typing you’re going to have to do because of your long variable names, let me introduce you to the wonderful new world of code completion.

So choose good, descriptive names and write them out.

6. Const Correctness

Const correctness is one of most beautiful programming principles that exists.

Const correctness will give you:

  • Code that “describes itself” well.
  • Code safety, at zero processing cost, since all const checks are done at compile time.
  • Faster code – apparently compilers can optimize better if you write const correct code.

If you don’t know what const correctness is or how to make things that way: shame on you!

Now read this: How to write C++ code that is const correct

7. Values, References and Pointers

One of the advantages C++ have over languages like Java and C#, is the ability for returns and parameters to be specified as copied values (e.g. int), references (e.g. int&) or pointers (e.g. int*).

The trick is to use them correctly.

If you combine the correct use of values, references and pointers, with code that is const correct, you get code that describes itself incredibly well.

Take as an example the following:

class MessageHandler {
    MessageRSP* send(MessageReq const& message) const {

From the declaration for the MessageHandler::send(…) function, we know that:

  • The function receives an existing ‘MessageReq’ object, because it is declared as a reference.
  • The function will use, but won’t change the the ‘MessageReq’ object, because it is constant.
  • The function may, or may not return a ‘MessageRSP’ object, because the function returns a pointer, which may be NULL.
  • If the function does not return NULL, the calling thread is probably responsible for deallocating the ‘MessageRSP’ object received, because it is not passed as a pointer to a constant object.

Go easy on the pointers. Wherever possible, always use values and references. When working with objects, pass by reference wherever possible (as in the above example with the ‘MessageReq’ parameter), to prevent the expensive operation of creating a new object that is associated with pass by value.

Use pointers only for basic arrays, if ownership is transferred (i.e. the calling thread has to deallocate a returned object), or if a parameter or return value may be NULL.

8. Namespaces

Namespaces are good. If anybody tells you otherwise, find a frying pan and hit them with it until they stop talking crap.

A class that is declared in the xyz::net::ip4 namespace as xyz::net::ip4::Addr, tells me that it is probably a class, created by the XYZ company, that is part of their networking library for handling IP version 4 type addresses.

If we weren’t using namespaces, what would the name of class ‘Addr’ say to me about that class?

Namespaces group classes, functions and variables into logical units.

It also makes it possible for the output of document generation and code completion utilities to be a lot more meaningful. I don’t know what else to say, it just makes sense to use them, and no sense not to.

9. Embedded Documentation

Tools like Doxygen allow you to generate documentation for your code, from comments you placed inside the code and from the code itself.

This is Gobsmackingly useful if you have to generate API reference documentation for your libraries, or if you to teach someone how to use your system.

By simply commenting your code in a certain way, you don’t only get to have well commented code, you also get API reference documentation in just about any format your heart desires.

10. Avoid Macros

When coding in C++, you should avoid using #define macros, wherever possible.

Macros are pre-compiler directives. Using macros are like wrapping a protocol inside another protocol, for something which should belong to the same protocol.

Furthermore, macros don’t get type-checked and they generally don’t work with documentation or code completion generators.

Rather use inline template functions for functions across types and const variables for constant declarations.

Tags: , , , , , ,

  1. Damian

    Thanks Francois.

    Quite a nifty beginners to intermediate engineers/programmers reference for learning C++.

  2. Alex Allain

    A very good list, but I noticed you didn’t mention RAII, which is, IMHO, a key C++ idiom. Also, RAII (in conjunction with templates) allows really great features like smart pointers–another feature that definitely makes my list.

    By the way, we have remarkably similar interests–I’m a big Vim fan too. Definitely glad to find your site.

  3. Francois Viljoen


    Pleased to meet you.

    I haven’t heard of the term ‘RAII’ before now, thanks for enlightening me.

    However, I do use the concept of RAII regularly (especially smart pointers) and I agree, it makes for very safe, logical and easy to use code.

    Definitely also a top-10 candidate!

Add a Comment