CAUTION!

CAUTION! DANGER ZONE ahead. Beware of misinformation on the open internet. Contents of the site are mere opinions and are not always facts!

Sunday, June 21, 2015

Lambda's for DRY'er code

Lambda's are inline anonymous functions/ functor's introduced in C++11. They are extensively used for higher order programming which helps in keeping the code DRY (Don't Repeat Yourself) by abstraction. Ex, Abstracting the collection iteration mechanics etc

Lambda's and closure's that had been supported by many dynamic programming languages for higher order/ functional programming are now supported by C++ with C++11. It helps in passing and returning functions like data.

let us consider abstracting collection iteration mechanics. STL provides many types of containers for storing a collection of data with iterators to access the data. The iterator's are used to iterate over all the elements in the container to perform operations on every element.

Example:
// A collection (vector) of 10 integers with value 1
std::vector<int> integer_collection(10, 1);

for(std::vector<int>::const_iterator it = integer_collection.begin(); it != integer_collection.end(); it++)
{
      std::cout << *it  << std::endl;
}
With higher order programming, the above code can be DRY'ed to the code below wherein all the iteration mechanism is abstracted into the
for_each
function. The third parameter passed to
for_each
is a lambda function which is called by
for_each
for every element in the vector. the lambda accepts an integer and performs the required operation.
std::for_each(integer_collection.begin(), integer_collection.end(), [](int &n){ 
      std::cout << n << std::endl;
});

Defining functions that take lambda's as parameters:
In the above example, what could be the prototype of
for_each()
i.e, What is the type of the lambda function?

1. The lambda's type can be prototyped with generic templating.
template<typename L>
void function(L lambda)// pass the right lambda!!
{
     lambda(10);// Beware, Compiler could complain if the lambda doesn't accept int parameter.
}

2. The lambda's without capture variables can be cast into function pointers.
void function(void (funptr*) (int x)) // lambda that takes int parameter returning void
{
     funptr(10); // call lambda
}

3. The lambda's type can be automatically deduced in C++11 with
auto
keyword.
void function(auto lambda)
{
     lambda(10);
}

4. The lambda's type can be defined with
std::function
defined in
<functional>
header from C++11.
void function(std::function<void(int)> lambda)// lambda that takes int parameter returning void
{
     lambda(10);
}

The lambda can not only be used as a functor object which can be passed to other functions. Closure's can be constructed i.e, the functions can access the variable's in the enclosing scope.

Simplified Syntax:
[capture variable's list - optional](additional parameter's - optional) { function body }


A simple example:
{
       int a, b, c;
       func([a, &b] (int x, double y) {
              // Call me back with a int and double
       });
}

The function func takes a lambda parameter which captures the variable
a
by value and
b
by reference and takes parameters
x
and
y
.

It should be noted that the advantages gained with lambda's can be achieved with function objects too. Thus, lambda's are syntactic sugar which eliminate the need to write function objects elsewhere in the code which is expected to be used only once, keeping the code DRY and in writing elegant functional programs.

Monday, April 13, 2015

RAII- Resource Acquisition Is Initialization

In C++, there is no automatic memory management/ Garbage collection which causes memory leaks. Unused memory should be deleted manually. Similarly, other resources not released even if not used causes resource leaks.

RAII is a commonly used OOP idiom to carefully manage resources. It is a scope based resource management style where the resource is acquired at the beginning of the scope and released at the end of the scope. The scope can be a block, a function or a class. The resources can be memory, files, mutexes etc

With RAII, The resources are acquired in the constructor and released in the destructor of the resource management class, so that the objects of this class can be declared in the required scope and the resources are re-claimed via the destructor when the objects go out of scope.

Here is an example of managing the memory with RAII. Do note that every class can do this management on its own. This example demonstrates RAII along with single responsibility principle. And so a class is exclusively written to manage the memory.

//Example for POD type. parameters for object construction and member access operator (->) are not considered.

template<typename T>
class CManagedMemory
{
     T *m_memory;
     CManagedMemory()
     {
          m_memory = new T(); // no more wild pointers!
     }
     //used for r value
     operator T()
     {
          return *m_memory;
     }
  
     // used for l value
     T operator=(T rVal)
     {
          *m_memory = rVal;
           return rVal;
     }
   
     ~CManagedMemory()
     {
          delete (m_memory);
          m_memory = NULL; // no more dangling pointers!
     }
};
The benefits of RAII are,

1. There are no resource leaks.

2. The resource variable is initialized to a valid state as soon as it is created and reset as soon as it is deleted.
    For example, a pointer which is not initialized - wild pointer - will have garbage value (pointing to a random address) or a pointer which is deleted - dangling pointer - points to reusable memory causes unexpected behavior. With RAII, the pointer is initialized when the managed memory object is declared.
    Without RAII,
 int *ptr; // contains garbage value
 delete(ptr); // contains dangling value

3. Custom define resource sharing, by appropriately declaring custom copy constructor, assignment operator as either private or public.

4. Resource is released automatically as soon as it is no longer needed. when the managed resource object goes out of scope, the destructor of the object releases the resource.
    Without RAII,
{
     int *ptr = new int();
}// memory leak. ptr should be deleted before the end of the block.
    With RAII,
{
     CManagedMemory<int> ptr;
}// memory deleted automatically

5. Resource reclaimed even on exceptions.
     Without RAII,
{
     int *ptr = new int();
     *ptr = 100 / 0; // divide by zero exception. Statements after this statement are not executed.
     delete (ptr);
}
    With RAII,
{
     CManagedMemory<int> ptr;
     ptr = 100 / 0; // divide by zero exception.
}// memory deleted even when the exception is thrown.

6. Code cleanliness. The code to reclaim the resource is in one place, in the destructor. The code need not be written in every procedure call or every branch.

C++11 introduces smart pointers like unique_ptr (no memory sharing), shared_ptr (shared memory) and weak_ptr for managing memory with RAII.

Sunday, February 8, 2015

Understanding data encapsulation

What is data encapsulation?

Data encapsulation is a fundamental OOP concept by which the data and the logic (a function) that uses/ manipulates it are bound together into objects.

How is data encapsulation useful?

Let us consider a problem which data encapsulation addresses. Consider 'C' language which is a sub set of 'C++' and does not support OOP/ data encapsulation. The C standard library provides the below strtok function which tokenizes the string "str" into sub strings separated by the delimiter "delim".

char *strtok(char *str, const char *delim)

The disadvantage of this function is that it cannot tokenize two strings simultaneously. This is because the tokenization requires multiple calls and the subsequent calls are dependent on the previous call. Also the corresponding delimiters for the two stings must be mapped manually for every call.

This link demonstrates the above problem. First token of str1 is printed and then the first token of str2. The next call tokenizes str2 and not str1 and prints the second token for str2.

So, how is data encapsulation helpful?

C++ is built on OOP paradigm where the complete functionality of a software is composed of objects with logically related sub functionalities. The objects consist of data and functions - data encapsulation.

This link demonstrates how the above problem is not seen in C++. The two strings are encapsulated into two different objects and the state of tokenization for each string is maintained separately in different objects. The delimiters are also bound to the tokenizers of each string.

This is one example of how data encapsulation or OOP is helpful.

The STL (C++ Standard Template Library) leverages this OOP concept to provide an enormous set of algorithms and containers.

Friday, January 16, 2015

CRTP

CRTP: Curiously Recurring Template Pattern.

let us consider a scenario which requires the pattern. I would like to design an abstract class to be implemented by the sub classes. Along with my API's, I have added some common members that every subclass must have - say, an id. And I would like to have a static member in each of my sub classes.

Approach: i added a static member in my abstract class. I have declared my static member in the class header and defined in the class cpp file.

problems:
1. All the translation units implementing the abstract class must also include the class cpp file for compilation or include the static library for the abstract interface.

2. The static member is shared accross all the instances of all the sub class types. but I would like to share one static member amongst all the instances of each sub class type.

CRTP to the rescue...

The abstract class is templated for the sub class type. One static member is created for each abstract class instantiation by the sub classes. Thus, the abstract class defines one static member for each sub class.

template<typename _subClass>
class AbstractClass
{

    static int m_staticMember;
    //...    

};

template<typename _subClass>
int AbstractClass<_subClass>::m_staticMember;


Saturday, December 13, 2014

Hands-on with QT

A record of solutions to issues that were resolved to develop a C++ QT windows desktop application. Only those that are not answered by search engines!

Development environment:
Processor: x64
OS: Windows 8.1 Pro
QT: 5.1.1

Work In Progress:

1. Application exited with code -1073741515
Background: application did not start and console reports the error code.
RCA: Run the application with debugger attached. Missing DLL reported in the error dialog. Navigate to the configured output folder. Run the exe. Windows explorer reports QTCored.dll missing.
Fix: Configure the environment variable "path" with the path to QT bin folder which contains the dependent debug libraries.

1. Application exited with code 0
Background: application did not start and console reports the error code.
RCA: No cause identified for the bug even under debug mode. The application exits even before the first line of main gets executed. Create a sample GUI application identical to the application not working (QMainWindow based). Check that it runs. Add required event listeners and check it still runs. Add cpp and h files iteratively and check it runs. Stop when it doesn't run anymore! On careful examination, there is another main present written for test which is not disabled by the TEST macro!!!
RC: Multiple Main found. Otherwise, trace the buggy code that terminates the application from the correct main.
Fix: Disable the test macro.



Saturday, October 25, 2014

Overloading functions with same signatures

The static polymorphism in C++ allows multiple functions with the same name offer different functionalities via function overloading. The overloaded functions vary in their signature and the compiler would resolve the function calls based on the parameters passed to the function. It is not possible to overload functions with same parameters. Sometimes, it is desirable to overload functions based only on the return type. One such scenario is shown below, where the data needs to be de-serialized into C++ POD types. The functions with same name and signature cause ambiguity in calling.

int get(Json::Value);
std::string get(Json::Value);

And thus the functions should either be renamed or emulate overloading. The disadvantage of renaming the functions to distinct names is that they cannot be called from other template functions or additional mechanism should be implemented by the template functions to determine the template parameter type and then call the suitable function.

int getInt(Json::Value);
std::string getString(Json::Value);

template<typename T>
struct POD
{
    T value;
    Json::Value operator=(Json::Value v)
    {
         value = ; //determine the type of T and call the suitable function for assignment 
         return v;
    }
};

Taking advantage of the type casting, it can be achieved by overloading the conversion/ type-cast operators. The casting can be either implicit or explicit.

struct Conv
{
    Json::Value val;

    Conv(Json::Value v) :val(v) { }
    operator std::string() { /*Convert and Return*/}
    operator int() { /*Convert and Return*/ }
};

int x = Conv(jsonVal); // create an anonymous object and convert

The overloading can also be achieved by template specialization and calling the required function explicitly.

namespace Conv
{
    template<typename T>
    T get(Json::Value); // linker complains for types not specialised
    template<>
    int get(Json::Value v)
    {
        /* Convert and Return*/
    }

    template<>
    std::string get(Json::Value v)
    {
        /* Convert and Return*/
    }
}

template<typename T>
struct POD
{
    T value;

    Json::Value operator=(Json::Value v)
    {
         value = Conv::get<T>(v);
         return v;
    }
};

Wednesday, September 17, 2014

Singleton pattern by inheritance

Singleton pattern is one of the fundamental design patterns used in OOP. The traditional way of implementing this is by making the constructor's private and providing a static member that can create the instance - Meyers singleton implementation. This is an implementation of the singleton pattern utility in c++ by inheritance, which imposes the pattern on the classes that derive from it. Any attempt to create the singleton class causes compilation error.

The implementation can be found here. It needs C++11 support for smart pointers , thread safety and variadic templates.

A single instance of the class is created and shared using smart pointers with the public static member. The singleton candidate is made non copyable so that multiple instances don't exist on copy by making the copy constructors private. In order to avoid the single state of the singleton candidate throughout the life time of the application, a weak pointer is used to store the instance. A shared pointer can be used if a global instance is desired. A tag is created for every singleton candidate which is accessible only to the singleton candidate, which prevents its creation from outside the utility class. It provides support for any signature of the singleton candidate constructor with the help of variadic templates.

The singleton candidate is expected to inherit from the utility class publicly and accept the tag as the first parameter in its constructors, which can be passed only by the utility class.

A sample singleton candidate is shown below.

#include<MySingleton.hpp>

class CSingletonCandidate : public CSingleton<CSingletonCandidate>
{
    private:
    int val;

    public:
    CSingletonCandidate(CSingletonTag<CSingletonCandidate>::TYPE tag, int v) : 
                        CSingleton(tag), 
                        val(v)
    {

    }
};

CSingletonCandidate::Type_T singleInstance = CSingletonCandidate::GetInstance<>(1);


This pattern is considered evil in some of the use cases and should be used cautiously. Singleton classes can also be used as a base class and the implementation of singletons should preserve the pattern even after being inherited and optionally allow multiple instances of the derived classes. This implementation  is strictly singleton and cannot be base class. It can be tweaked to support derived class in which case the base class/ singleton candidate is not strictly singleton and the derived classes can create its instances. The derived classes can further be singletons by using the utility class.

The caveat is that the singleton candidate itself can create loopholes to tarnish the singleton pattern.