0

I am reading a book about data structures and I stumbled upon this block of code:

class UnorderedArray 
{
public:
UnorderedArray(int size, int growBy = 1) :
    m_array(NULL), m_maxSize(0), m_growSize(0), m_numElements(0)
{
    if (size) {
        m_maxSize = size;
        m_array = new T[m_maxSize];

        m_growSize = ((growBy > 0) ? growBy : 0);
    }
}

private:
T * m_array;

int m_maxSize;
int m_growSize;
int m_numElements;

}

Can someone explain this block of code for me?

UnorderedArray(int size, int growBy = 1) :
m_array(NULL), m_maxSize(0), m_growSize(0), m_numElements(0)

I believe this is some sort of initialization for those variables but I can't seem to find a concrete answer.

Dale Julian
  • 1,560
  • 18
  • 35

3 Answers3

2

Yes, the code initializes the variables to the values in the parentheses. This feature of C++ is known as initialization lists.

As indicated in the Standard C++ FAQ, when writing class constructors you should prefer using member initialization lists to assignment:

Consider the following constructor that initializes member object x_ using an initialization list: Fred::Fred() : x_(whatever) { }. The most common benefit of doing this is improved performance. For example, if the expression whatever is the same type as member variable x_, the result of the whatever expression is constructed directly inside x_ — the compiler does not make a separate copy of the object. Even if the types are not the same, the compiler is usually able to do a better job with initialization lists than with assignments.

The other (inefficient) way to build constructors is via assignment, such as: Fred::Fred() { x_ = whatever; }. In this case the expression whatever causes a separate, temporary object to be created, and this temporary object is passed into the x_ object’s assignment operator. Then that temporary object is destructed at the ;. That’s inefficient.

As if that wasn’t bad enough, there’s another source of inefficiency when using assignment in a constructor: the member object will get fully constructed by its default constructor, and this might, for example, allocate some default amount of memory or open some default file. All this work could be for naught if the whatever expression and/or assignment operator causes the object to close that file and/or release that memory (e.g., if the default constructor didn’t allocate a large enough pool of memory or if it opened the wrong file).

Conclusion: All other things being equal, your code will run faster if you use initialization lists rather than assignment.

In other words, the code as shown is preferable to the alternative code where the class's member variables are initialized in the body of the constructor:

UnorderedArray(int size, int growBy = 1)
{
    m_array = NULL;
    m_maxSize = 0;
    m_growSize = 0;
    m_numElements = 0;

   if (size) {
        m_maxSize = size;
        m_array = new T[m_maxSize];

        m_growSize = ((growBy > 0) ? growBy : 0);
    }
}
Lisbeth
  • 129
  • 2
  • 11
0

UnorderedArray is the class,

UnorderedArray(int size, int growBy = 1):

Is the signature for a constructor taking one or two integers, and if the second integer is not provided, it defaults to one (ie if you don't provide an argument it's one).

m_array(NULL), m_maxSize(0), m_growSize(0), m_numElements(0)

Is explicitly member initialization, it sets m_array to Null, m_maxSize to 0, m_growSize to 0, and m_numElements to 0.

Daniel
  • 854
  • 7
  • 18
0

As songyuanyao comment indicates, this is called an initializer list and is explained in depth at cpp reference. This m_array(NULL) is equivalent to m_array = NULL in the body of the constructor.

Jonathon K
  • 339
  • 2
  • 6