Read one line from a text file

File stream is great for reading data to and from files,. Mainly because it always makes sure to close the file when the object goes out of scope, which means that we don’t need to remember to call close(), but also because it makes it possible to parse the contents of the file.

Sometimes we don’t want to parse the contents but just read the data one line at a time.

 

Facebookgoogle_pluslinkedinmail

Exception safety

Exception safety is about taking care of the resources that you are using, such as allocated memory or opened files, both in the happy path through your code and in the case of an exception being thrown.

The problem lies in code such as

What happens to the memory which is allocated dynamically for the array if the function bar throws an exception? What surprises many developers is that the execution will skip all code lines after the call to bar in the local function and continue with the first line in the appropriate exception handler. The line where the dynamically array is deleted (using delete[]) is not going to be called at all! This means that the code in the example above is not exception safe, when an exception is thrown then the code will leak memory.

Even though all code lines after the call to bar will be skipped, all the local variables (i.e. allocated on the stack) declared in the function foo are going to be cleaned up. And this is a feature which C++ uses to deal with exception safety. The technique is called RAII (Resource Acquisition is Initialization) and stores variables and data structures on the local stack instead of on the free store directly. Now you object that it is impossible to always store all the data on the stack, you may not know how much data you are going to need when you write the program. The size of a variable is something which you probably want to determine at run time, depending on the input data to your program.

The C++ solution to this is to store a handle to the memory that you have allocated on the free store on the local stack. When that handle goes out of scope its destructor will be called and you simply make sure that you delete all the memory used in the destructor. This is the basic concept of the standard library containers, such as vector, list or map, or the smart pointers shared_ptr and unique_ptr.  To convert the example above into exception safe code, replace the call to the dynamic memory allocation into using std::vector like this.

The instance of the vector is allocated on the local stack, but internally it will call new[] to allocate the memory for the 25 values on the free store. When the vector goes out of scope, either because the function ends or an exception is thrown, then the destructor of the vector is going to be called and this will delete all the memory that was allocated on the free store.

The C++ standard library containers and data structures all use the RAII technique for making sure that no resources are being leaked. When you create a new class you should also use the RAII technique to make sure your code is exception safe. Other developers who are using or modifying your code expect that you have taken care of releasing the resources that you are using and don’t want to worry about cleaning up the mess after you. Make the C++ code that you write developer friendly and clean up your own mess!

Facebookgoogle_pluslinkedinmail

Variables on the stack

I think one very underused feature in C++ today is simply storing objects on the stack. Many developers who have started writing C# or Java are used to always using new to declare a variable and do the same thing when they are writing C++. And when they later learn that you should never write a naked new, they instead start using unique_ptr or shared_ptr to manage the lifetime of their objects. What they are forgetting is that many times is it sufficient to simply store the instance that you are creating on the stack as a solid object, either as a member of a class or in the local function scope.

The standard library does this all the time, you write

never ever

If you are certain what type of object you need and when you need it, then simply put it on the local stack!

For often called methods you will get a performance increase by doing this since the allocation of an object on the free store takes some time (new has to locate a free portion of memory to allocate).

The exceptions where you don’t want to allocate the object on the local stack include cases where you may want polymorphic behavior, or the class contains large amounts of data making the object too large for the stack.

Facebookgoogle_pluslinkedinmail

Why should I use nullptr instead of NULL?

C++11 introduced the new keyword nullptr which is used to indicate a null pointer. This is different from the old NULL which was just a zero (usually an integer).

To understand why nullptr was introduced, consider the following example:

the developer probably intended to call the overload of f taking a pointer. However, since NULL is not a pointer but an integer, the overload of f taking an integer is going to be called.

If the developer instead wrote:

then the code would be much more clear in its intent.

Facebookgoogle_pluslinkedinmail

Why you should always use a virtual destructor

Virtual destructors are a must when you can delete an object through a pointer to a base class. Let me explain.

Say that you have a simple base class:

and a class deriving from the BaseClass with the addition of a resource which is supposed to be managed using RAII:

now what happens when you use this class:

since the base class doesn’t have a virtual destructor and ‘obj’ is pointing to a BaseClass, not to a DerivedClass, then the destructor of BaseClass is going to be called, but not the destructor of DerivedClass!! This means that the managed resource in DerivedClass is not going to be deleted properly when the object is deleted and thus we have a memory leak!

If instead the BaseClass would have a virtual destructor, like this:

then the constructors would be called in both the base class and the derived class and all contents will be correctly released.

Facebookgoogle_pluslinkedinmail

Range-based for

With C++11 we got a new way of writing for-loops to iterate over all elements in a range. The new range-based for loop is much clearer than the old way using iterators. It is intended to be used when you only look at the elements in a container, you are not supposed to change the container itself since this could cause problems in the loop.

An example of how the new range-based for works, using a vector as an example:

When the vector contains an object then it’s a good idea to get a reference to the object to avoid copying the entire object in each round in the loop.

If the contents of the vector shouldn’t be changed then we can show this by getting a const reference:

We can use the auto keyword to avoid explicitly giving the type:

 

Facebookgoogle_pluslinkedinmail

RAII – Resource Acquisition Is Initialization

Resource Acquisition is Initialization (or RAII for short, usually pronounced by simply spelling out the letters R-A-I-I) is a programming technique where we make sure that resources are cleaned up when they are no longer needed by tying a resource to an object. The resource is kept as long as the object is alive and automatically released when the object is destroyed.

The resource that is being managed can be a segment of memory, a file handle, a network socket, a database handle or anything else which there is just a limited number of in the system and which we need to make sure we close properly after we are done with it.

The way RAII works is that we tie the resource to a class. When an instance of the class is created then the constructor of the object’s class is called to create the resource (or passed the resource to be managed). When the object is later destroyed (by going out of scope) then the destructor will automatically be called and here we write the code to release the resource again.

The name is somewhat difficult and controversial, some have suggested instead calling it Scope-Bound Resource Management but this has so far not been too successful.

I think an example of what I mean is necessary here. In the example below is a segment of memory allocated (using new[]) in the constructor of the File class and the memory is released again (using delete[]) in the destructor. The neat thing here is that the destructor will automatically be called when the object goes out of scope, as is done when the function main() in the example exits.

Notice: this is only done automatically for you if the File object is allocated as a local object, this is one of the reasons why you should never use new or delete.

The benefits of RAII is that it creates:

  • exception safety: a stack object will be destroyed at the end of the enclosing scope,  also if an exception is thrown from the code after the object is created.
  •  good locality: the code for allocating the resource is in the same class as the code for releasing the resource again.
  • encapsulation: the managed resource is located inside the owning class and not accessible outside of it.

Because of its benefits is RAII used extensively throughout the standard library classes.

As an example, the following code is using old C functions to write data to a text file NOT using RAII.

In the example above we didn’t use RAII to hold on to the resource (which in this case is the file handle FILE* f). This makes the code not exception safe, if anyone would later add a function call after the file has been opened and this method throws an exception then the call to fclose will not be executed at all, leaving the file opened and locked.

A better example is to instead use the standard library to open and write to the file:

in this example does the instance of the standard library class std::ofstream which we create on the first line hold on to the file resource and when the object goes out of scope when the function ends then the file will be closed automatically for us. Notice how much shorter and cleaner this code becomes. We don’t have to worry about closing the file since this is done for us.

References

  1. Stroustrup: Why doesn’t C++ provide a “finally” construct?

 

Facebookgoogle_pluslinkedinmail

Scope

The scope of a variable determines who can see and use the variable and for how long the variable will be available until it is destroyed.

Local scope

Function parameters and variables declared inside a function (local variables) have local scope. That is to say that they can only be seen inside the function that declares them. The local variables are destroyed when the function exits and can no longer be accessed after the function exits.

Local scope prevents naming collisions. It is possible to have two variables with the same name, as long as they are in different scopes!

Be aware that it is possible to have nested scopes where two variables can exist with the same name but in different scopes, one inside another.

What happens in the example above is that within the nested block is a new variable ‘x’ created and this variable has its scope set to the local block which is smaller than the function main. Inside the nested scope is the outer variable ‘x’ not accessible it is hidden from view (this is called name hiding), only the variable ‘x’ declared in the inner scope can be seen and modified.  Notice that it is generally bad practice to declare a new variable with the same name is a smaller scope. The code quickly gets much more confusing when you have to remember which variable with the name ‘x’ you are seeing.

In the same way is it possible to declare a local variable with the same name as a function parameter.

This is also a bad practice and should always be avoided since it makes the code so much more difficult to read.

 

Facebookgoogle_pluslinkedinmail

The const keyword

The const keyword is used to show both other developers and the compiler that an object is constant and its contents cannot be changed. If you anyway try to change the contents of a const object will generate an error already at compile time. It is a good practice to add the const keyword to a parameter, a members or a method to show that the value is not going to be changed. This can both make the intent of the code more clear to the user, and can make the code faster since the compiler can make certain optimizations knowing that the object is not going to change its value.

The difference between the const keyword and the constexpr keyword is that the value of a constexpr constant must be resolved at compile time whereas the value of a const constant can be resolved at run time (or at compile time).

The const keyword can be used in the following contexts:

Const class

An object can be made constant at creation by declaring the object as const:

Any attempt to change the contents of the object christmasDay will result in a compiler error:

 

Const member functions

Adding the const keyword to a member function (added at the end of the function declaration, after the parameters) states that this method will not change the state of the object.

The const keyword after the declaration of the method getYear() shows that calling this method will not change any members of the object. This also means that we are allowed to call this method even if the object is const.

 

Const parameters

Parameters to functions can also be declared as const. There are two positions where the const keyword can be added.

 

 

 

Facebookgoogle_pluslinkedinmail