Constructor – creating the object

The constructor is a special function used to setup an object to a valid state.

  • The constructor must have the same name as the class.
  • The constructor does not have a return type.
  • There can be many constructors for the same class, the difference between them is the number and type of the parameters.

A constructor without any parameters is called the default constructor. If you don’t write a default constructor then one will be created for you automatically and setup the object with default values (which may not be what you want).

The constructor of the object is together with the destructor an important part of the RAII paradigm.

Multiple constructors

A class can have many constructors, and one common problem is that these will usually perform the same initialization of the member variables thereby creating redundant code. With the interest of keeping your code DRY, you should consider to extract the common elements into separate functions. The, in many cases, most natural solution to this would be to make the constructors call each other – but there is a pitfall here. Calling one constructor from another will only work in C++11, so if you have a compiler which supports C++11 you can do the following (called delegating constructors):

If you don’t have a C++11 compiler then the common solution is to extract a separate function which does the initialization:

 

Private Constructor

Normally is the constructor of a class a public member function. If a class has a private constructor, then it is not possible to create instances of the class anywhere else but in the class itself. This can be handy if you want all instances to be created in exactly the same way or in the same location using a static factory method.

 

 

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

Memory leaks in constructions

Say that you have found somewhere deep in the darkest basement the following line of code

then you have found a potential memory leak in your program.

Why?

Remember that, calling new Date() will:

  1. Allocate memory for Date
  2. Construct the new Date object in that memory. If the construction fails because of an exception, then the allocated memory is freed again.

The compiler is free to evaluate the expressions in any way it seems suitable (the reason for this is that it has the ability to optimize the code if given some slack, see order of evaluation).  It can for example do like this:

  1. Allocate memory for Date
  2. Construct Date
  3. Allocate memory for Time
  4. Construct Time
  5. Call fun

The problem here is that if either step 3 or step 4 fails because of an exception, the C++ standard does not require that the Date object must be destroyed and its memory deallocated. This is a memory leak!

Another possibility is that the compiler does this:

  1. Allocate memory for Date
  2. Allocate memory for Time
  3. Construct Date
  4. Construct Time
  5. Call fun

In this case, then there are actually two problems.

1) If step 3 fails because of an exception, then the memory allocated for Date is automatically deallocated (step 1 is undone), but the standard does not require that the memory allocated for the Time object be deallocated. The memory is for the Time object is leaked.

2) If step 4 fails because of an exception, then the Date object has been allocated and fully constructed, but the standard does not require that it be destroyed and its memory deallocated. The memory of the Date object is leaked.

 

 

 

 

Facebookgoogle_pluslinkedinmail