Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are your favorite C++ Coding Style idioms [closed]

RAII: Resource Acquisition Is Initialization

RAII may be the most important idiom. It is the idea that resources should be mapped to objects, so that their lifetimes are managed automatically according to the scope in which those objects are declared.

For example, if a file handle was declared on the stack, it should be implicitly closed once we return from the function (or loop, or whichever scope it was declared inside). If a dynamic memory allocation was allocated as a member of a class, it should be implicitly freed when that class instance is destroyed. And so on. Every kind of resource—memory allocations, file handles, database connections, sockets, and any other kind of resource that has to be acquired and released—should be wrapped inside such a RAII class, whose lifetime is determined by the scope in which it was declared.

One major advantage of this is that C++ guarantees that destructors are called when an object goes out of scope, regardless of how control is leaving that scope. Even if an exception is thrown, all local objects will go out of scope, and so their associated resources will get cleaned up.

void foo() {
  std::fstream file("bar.txt"); // open a file "bar.txt"
  if (rand() % 2) {
    // if this exception is thrown, we leave the function, and so
    // file's destructor is called, which closes the file handle.
    throw std::exception();
  }
  // if the exception is not called, we leave the function normally, and so
  // again, file's destructor is called, which closes the file handle.
}

Regardless of how we leave the function, and of what happens after the file is opened, we don't need to explicitly close the file, or handle exceptions (e.g. try-finally) within that function. Instead, the file gets cleaned up because it is tied to a local object that gets destroyed when it goes out of scope.

RAII is also less-commonly known as SBRM (Scope-Bound Resource Management).

See also:

  • ScopeGuard allows code to "automatically invoke an 'undo' operation .. in the event that an exception is thrown."

When creating enumerations, put them in a namespace so that you can access them with a meaningful name:

namespace EntityType {
    enum Enum {
        Ground = 0,
        Human,
        Aerial,
        Total
    };
}

void foo(EntityType::Enum entityType)
{
    if (entityType == EntityType::Ground) {
        /*code*/
    }
}

EDIT: However, this technique has become obsolete in C++11. Scoped enumeration (declared with enum class or enum struct) should be used instead: it is more type-safe, concise, and flexible. With old-style enumerations the values are placed in the outer scope. With new-style enumeration they are placed within the scope of the enum class name.
Previous example rewritten using scoped enumeration (also known as strongly typed enumeration):

enum class EntityType {
    Ground = 0,
    Human,
    Aerial,
    Total
};

void foo(EntityType entityType)
{
    if (entityType == EntityType::Ground) {
        /*code*/
    }
}

There are other significant benefits from using scoped enumerations: absence of implicit cast, possible forward declaration, and ability to use custom underlying type (not the default int).


Copy-swap

The copy-swap idiom provides exception-safe copying. It requires that a correct copy ctor and swap are implemented.

struct String {
  String(String const& other);

  String& operator=(String copy) { // passed by value
    copy.swap(*this); // nothrow swap
    return *this; // old resources now in copy, released in its dtor
  }

  void swap(String& other) throw() {
    using std::swap; // enable ADL, defaulting to std::swap
    swap(data_members, other.data_members);
  }

private:
  Various data_members;
};
void swap(String& a, String& b) { // provide non-member for ADL
  a.swap(b);
}

You can also implement the swap method with ADL (Argument Dependent Lookup) directly.

This idiom is important because it handles self-assignment[1], makes the strong exception guarantee[2], and is often very easy to write.


[1] Even though self-assignment isn't handled as efficiently as possible, it's supposed to be rare, so if it never happens, this is actually faster.

[2] If any exception is thrown, the state of the object (*this) is not modified.


CRTP: Curiously Recurring Template Pattern

CRTP happens when you pass a class as a template parameter to its base class:

template<class Derived>
struct BaseCRTP {};

struct Example : BaseCRTP<Example> {};

Within the base class, it can get ahold of the derived instance, complete with the derived type, simply by casting (either static_cast or dynamic_cast work):

template<class Derived>
struct BaseCRTP {
  void call_foo() {
    Derived& self = *static_cast<Derived*>(this);
    self.foo();
  }
};

struct Example : BaseCRTP<Example> {
  void foo() { cout << "foo()\n"; }
};

In effect, call_foo has been injected into the derived class with full access to the derived class's members.

Feel free to edit and add specific examples of use, possibly to other SO posts.


pImpl: Pointer-to-Implementation

The pImpl idiom is a very useful way to decouple the interface of a class from its implementation.

Normally, a class definition must contain member variables as well as methods, which may expose too much information. For example, a member variable may be of a type defined in a header that we don't wish to include everywhere.

The windows.h header is a prime example here. We may wish to wrap a HANDLE or another Win32 type inside a class, but we can't put a HANDLE in the class definition without having to include windows.h everywhere the class is used.

The solution then is to create a Private IMPLementation or Pointer-to-IMPLementation of the class, and let the public implementation store only a pointer to the private one, and forward all member methods.

For example:

class private_foo; // a forward declaration a pointer may be used

// foo.h
class foo {
public:
  foo();
  ~foo();
  void bar();
private:
  private_foo* pImpl;
};

// foo.cpp
#include whichever header defines the types T and U

// define the private implementation class
class private_foo {
public:
  void bar() { /*...*/ }

private:
  T member1;
  U member2;
};

// fill in the public interface function definitions:
foo::foo() : pImpl(new private_foo()) {}
foo::~foo() { delete pImpl; }
void foo::bar() { pImpl->bar(); }

The implementation of foo is now decoupled from its public interface, so that

  • it can use members and types from other headers without requiring these dependencies to be present when the class is used, and
  • the implementation can be modified without forcing a recompile of the code that uses the class.

Users of the class simply include the header, which contains nothing specific about the implementation of the class. All implementation details are contained inside foo.cpp.


I like lining up code/initializations in 'columns'... Proves very useful when editing with a 'column' mode capable editor and also seems to be a lot easier for me to read...

int myVar        = 1;    // comment 1
int myLongerVar  = 200;  // comment 2

MyStruct arrayOfMyStruct[] = 
{   
    // Name,                 timeout,   valid
    {"A string",             1000,      true    },   // Comment 1
    {"Another string",       2000,      false   },   // Comment 2 
    {"Yet another string",   11111000,  false   },   // Comment 3
    {NULL,                   5,         true    },   // Comment 4
};

In contrast, the same code not indented and formatted as above would appear... (A little harder to read to my eyes)

int myVar = 1; // comment 1
int myLongerVar = 200; // comment 2

MyStruct arrayOfMyStruct[] = 
{   
    // Name, timeout, valid
    {"A string", 1000, true},// Comment 1
    {"Another string", 2000, false }, // Comment 2 
    {"Yet another string", 11111000,false}, // Comment 3
    {NULL, 5, true }, // Comment 4
};

Public Top - Private Down

A seemingly small optimization, but ever since I switched to this convention, I have a way more fun time to grasp my classes, especially after I haven't looked at them for 42 years.

Having a consistent member visibility, going from points of frequent interest down to the boring stuff, is extremely helpful, especially when the code ought to be self-documenting.

(sidenote for qt-users: slots come before signals because they should be callable like non-slot member functions, and apart from their slottyness be indistinguishable from non-slots)

  • Public, protected, private
  • then Factory, ctor, dtor, copying, swapping
  • then the class' Interface At the very last, in a seperate private: section, comes the data (ideally only an impl-pointer).

This rule also helps a ton if you have problems keeping your class declaration uncluttered.

class Widget : public Purple {
public:
    // Factory methods.
    Widget FromRadians (float);
    Widget FromDegrees (float);

    // Ctors, rule of three, swap
    Widget();
    Widget (Widget const&);
    Widget &operator = (Widget const &);
    void swap (Widget &) throw();

    // Member methods.
    float area() const;

    // in case of qt {{ 
public slots:
    void invalidateBlackHole();

signals:
    void areaChanged (float);
    // }}

protected:    
    // same as public, but for protected members


private:    
    // same as public, but for private members

private:
    // data
    float widgetness_;
    bool  isMale_;
};