Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using new in a member initializer list of constructor [duplicate]

Tags:

c++

This compiles, but I've never seen it in any other code. Is it safe?

Testclass():sources(new int[32]){}

Instead of:

Testclass(){
    sources = new int[32];
}
like image 621
johnbakers Avatar asked Feb 04 '13 06:02

johnbakers


1 Answers

Use:

Testclass():sources(new int[32]){}

This is using member-initialization-list which is the preferred way to initialize members.

By "safe" or "okay" you probably meant, whether it is exception-safe? What if new throws the bad_alloc exception?

Well, in that case, the destructor will not be called, because the object is not fully-constructed, as constructor-body is not executed. There may be a resource leak if you've acquired any resource in the initialization list.

Consider this,

class X
{
    int  *ints;  // Order of declaration matters!
    Huge *huges; // It ensures that huges will be initialized after ints

    X() : ints(new int[32]), huges(new Huge[10000]) {}
};

If new Huge[10000] throws an exception, the memory allocated toints will leak!

In such cases, function-try-block can be useful. See these:

  • Function try blocks, but not in constructors
  • What is the purpose of a function try block?

If you think about this problem of exception-safety, you will soon realize that if a class manages just one resource, then the life will be easier. If a single class manages more than one resource, then you wouldn't be able to decide which one threw an exception in the member-initialization-list, and consequently, you wouldn't be able to decide which one is to be deallocated in the catch block of function-try-block. A resource leak is destined.

However, if a class needs more than one resource, then first you encapsulate each of the different type of resource in a class, and declare objects of these resource-managing class as a member of your class.

like image 184
Nawaz Avatar answered Sep 21 '22 19:09

Nawaz