Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Must a reference type be initialized in constructor initialization list?

Tags:

c++

reference

As self-exercise, I have written this simple code:

#include <iostream>

int gIndex = 3;

template <class T> class Array
{
public:
    explicit Array(int size);
    T& operator[](int i) { return m_data[i]; }
    T operator[](int i) const { return m_data[i]; }
    T getAnchorPoint() const { return m_data[m_anchor]; }
private:
    T* m_data;
    int m_size;
    int& m_anchor;
};

template <class T> Array<T>::Array(int size) : m_size(size), m_data(new T[size])
{
    memset(m_data, 0, size*sizeof(T));
    m_anchor = gIndex;
}

int main()
{
    Array<double> a(10);
    return 0;
}

I got a compilation error , which says:

error C2758: 'Array<T>::m_anchor' : must be initialized in constructor base/member initializer list

It has never happened , what brings me to ask this question:

Must any class-member reference type be initialized in the constructor initialization list?

If so, why? Is that related somehow to the fact that a reference type can never be reassigned?

Are there more types that must be initialized in constructor initialization list?

like image 592
Billie Avatar asked Aug 01 '13 10:08

Billie


People also ask

Do references have to be initialized?

A reference can be declared without an initializer: When it is used in a parameter declaration. In the declaration of a return type for a function call. In the declaration of class member within its class declaration.

What is initialization list in constructor?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

Should my constructors use initialization lists or assignment?

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


2 Answers

Does any class-member reference type must be initialized in the constructor initialization list?

Yes.

If so, why? Is that related somehow to the fact the a reference type can never be reassigned?

That's part of the reason. The other part is because a reference must be initialized, and it has no default constructor.

Are there more types that must be initialized in constructor initialization list?

Any type that doesn't have an assignment operator (be it copy or move) or default constructor. This obviously includes (but is not limited to) const members as they can't be modified once they've been constructed.


As a rule of thumb, you should (almost) always prefer to initialize your members in the constructor's initialization list: why waste cycles first default-constructing an object and then only assigning to it (if this is even possible), when you could construct it correctly in the first place?

like image 99
syam Avatar answered Oct 02 '22 16:10

syam


Must any class-member reference type be initialized in the constructor initialization list?

Yes.

Is that related somehow to the fact that a reference type can never be reassigned?

Yes, plus the fact that there is no "null" or default construction for a reference. It is an alias for another object, and it has to be bound to it from the outset. You cannot do this (this is not inside a class definition):

int main()
{
  int& iref; // ERROR
  int i = 42;
  int& iref2 = i; // OK
}

because iref must alias something.

like image 25
juanchopanza Avatar answered Oct 02 '22 15:10

juanchopanza