Programming Idioms Part 1.

C++ Programming Idioms Part 1.

Requirements:
Linux Distribution
g++
any text editor

My Setup:
Debian 10
g++ version 6.3.0
pluma

Today i will be going over some basic programming idioms that are generally
used by C++ developers. These are acronyms to phrases that describe concepts
the C++ language feature.

1. Resource Aquisition Is Initialization (RAII)
According to cppreference, “Resource Acquisition Is Initialization or RAII,
is a C++ programming technique which binds the life cycle of a resource that
must be acquired before use (allocated heap memory, thread of execution, open
socket, open file, locked mutex, disk space, database connection—anything that
exists in limited supply) to the lifetime of an object. RAII guarantees that
the resource is available to any function that may access the object
(resource availability is a class invariant, eliminating redundant runtime
tests). It also guarantees that all resources are released when the lifetime of
their controlling object ends, in reverse order of acquisition. Likewise, if
resource acquisition fails (the constructor exits with an exception), all
resources acquired by every fully-constructed member and base subobject are
released in reverse order of initialization. This leverages the core language
features (object lifetime, scope exit, order of initialization and stack
unwinding) to eliminate resource leaks and guarantee exception safety. Another
name for this technique is Scope-Bound Resource Management (SBRM), after the
basic use case where the lifetime of an RAII object ends due to scope exit.”
They also give a good example of the use of RAII :

std::mutex m;

void bad()
{
    m.lock();                    // acquire the mutex
    f();                         // if f() throws an exception, the mutex is never released
    if(!everything_ok()) return; // early return, the mutex is never released
    m.unlock();                  // if bad() reaches this statement, the mutex is released
}

void good()
{
    std::lock_guard<std::mutex> lk(m); // RAII class: mutex acquisition is initialization
    f();                               // if f() throws an exception, the mutex is released
    if(!everything_ok()) return;       // early return, the mutex is released
}                                      // if good() returns normally, the mutex is releas

As you can see, once the function ends, the mutex that is on the stack gets
implicitly released as the function returns .There are three parts to an RAII
class:

1. (Optional) The resource is aquired in the constructor
2. Instances of the class are stack allocated
3. The resource aquired within the constructor is released in the destructor

For more information on RAII , check out the following : https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Resource_Acquisition_Is_Initialization

2. Curiously Recurring Template Pattern (CRTP)

The Curiously Recurring Template Pattern is quite interesting. It is a
concept where one Derived class is extended from its base class that takes
the Derived class as a parameter. I can better explain with code:

CRTP
template<class X>
class Base
{
    // methods within Base can use template to access members of Derived
};

class Derived : public Base<Derived>
{
    // ...
};

Now what does this do exactly and how can I use it , you may ask. Well this
allows you to specialize a base class using the derived class as a template
argument. Lets look more into how we can use this from an example from
:

template <class Derived>
 struct base
 {
     void interface()
     {
         // ...
         static_cast<Derived*>(this)->implementation();
         // ...
     }

     static void static_interface()
     {
         // ...
         Derived::static_implementation();
         // ...
     }

     // The default implementation may be (if exists) or should be (otherwise) 
     // overridden by inheriting in derived classes (see below)
     void implementation();
     static void static_implementation();
 };

 // The Curiously Recurring Template Pattern (CRTP)
 struct derived_1 : base<derived_1>
 {
     // This class uses base variant of implementation
     //void implementation();

     // ... and overrides static_implementation
     static void static_implementation();
 };

 struct derived_2 : base<derived_2>
 {
     // This class overrides implementation
     void implementation();

     // ... and uses base variant of static_implementation
     //static void static_implementation();
 };

Lets say you are writing a game engine. You may use this to interface between
rendering types . Maybe you wrote a DirectXRenderer class that extends from
Renderer<T> , as well as an OpenGLRenderer and OpenGLESRenderer. This allows you
to use your base class (Renderer<T>) to call the inner functions of the specific
renderers.

 

One thought on “Programming Idioms Part 1.

Leave a Reply