Interfaces done right

Interfaces are one of the backbones of modern, object-oriented design. You need to use instances of different classes which share similarities in a uniform way? Use interfaces. You cannot easily test a class because it depends on details of other classes? Make your class depend on interfaces instead and introduce mock objects. You have a class with a single responsibility, but a respectable amount of methods which are intended for different types of callers? Make your class implement several interfaces, and let different callers refer to the ones which suit their needs.

As you can see, interfaces used correctly are pretty powerful tools, and many programming languages such as Java and C# provide dedicated interface keywords. This is not the case for C++. This article explains how to write clean and safe interfaces for your classes.

Continue reading “Interfaces done right”

Mandatory template arguments

Consider the following function declaration:

template <typename ... Items_To_Print>
void print_as_csv(std::ostream & stream, char delimiter, Items_To_Print && ... items_to_print);

Though the declaration may seem rather involved, the actual application of this function is quite simple:

print_as_csv(std::cout, ';', 2.0, 42, "hello");

The compiler knows how to create an instance of print_as_csv by a mechanism called template argument deduction. It works only for functions, because the compiler needs arguments to deduce the types from. There are, however, template functions for which not all template arguments can be deduced by the compiler.

Continue reading “Mandatory template arguments”

I like to std::move it

A little while ago while I was surfing the web I stumbled on a blog of a C++ programmer. Sadly, I was unable to retrace my steps, so I will have to reconstruct what I found there from memory. The programmer was faced with the task of multiplying two matrices with each other. The result is yet another matrix. Efficiency and ease of use were important criteria. Here is the relevant part of the code:

matrix & matrix::operator* (matrix const & other) const
{
	// snip: ... assert matrix sizes are compatible ...
	matrix * result = new matrix(rows(), other.columns());
	// snip: ... compute and store matrix elements ...
	return *result;
}

Let us put on our CSI C++ hat for a while.

Continue reading “I like to std::move it”

May the FORs be with you

Loops are among the basic constructs you find in nearly all programming languages. Of the available variations, for loops are the most common ones. The word for is so small that it is not affected by the tax on long keywords and variable names that programming languages seem to be subject of. Thus, you will find for as a keyword in most of them.

C++11 supports a multitude of styles to write for loops. Let us have a look at some of these possibilities for a simple example.

Continue reading “May the FORs be with you”

Mopping up template barf with static_assert

Templates are a mixed blessing for C++ developers. On the one hand, templates avoid code duplication as most impressively demonstrated by the standard template library. The template mechanism, in contrast to preprocessor macros, is aware of the C++ language and part of it. Compilers can produce helpful error messages – and some compilers even do so.

Some compilers, however, fail in providing clear template compilation error messages. If you make a mistake, you are greeted by a bucket load of irritating notes on what went wrong in detail. Since it is down to you to identify the relevant chunks, this is often referred to as template barf.

Continue reading “Mopping up template barf with static_assert”

Underprivileged unique pointers: retrofitting make_unique

std::shared_ptr<Value> is one of the starlets in C++11’s recently polished standard template library. shared_ptrs work just like normal C-style pointers except that they keep track of how many pointers point to the same object. Once the last shared_ptr pointing to an object goes out of scope, the object pointed at will be deleted. For convenience, the standard library offers the factory function std::make_shared<Value>():

auto value = std::make_shared<Value>("a", "few", "arguments");

std::make_shared<Value>() creates a new object of type Value, where the arguments given to make_shared() are forwarded to the constructor of Value. The newly created object is immediately wrapped in a std::shared_ptr<Value>, which is then returned to the caller.

Continue reading “Underprivileged unique pointers: retrofitting make_unique”

Resource management

Most computer programs rely on resources provided by the operating system or another software. The most common resource is memory, closely followed by files on the local file system. Be it a chunk of memory or a database connection, resources should be dealt with gently; return them once you no longer need them.

Many text books and university courses on C++ familiarize the programmer with low-level functions such as new and delete. These mechanisms are inconvenient and error-prone since you need to make sure that you release the resource no matter which execution path your program takes. Less obvious paths, for example exceptions in the control flow, tend to be forgotten.

Continue reading “Resource management”