Why use contructor init lists?

What is the benefit of using constructor initialization lists as opposed to initializing variables in the body of the constructor. I often find the lists confusing and difficult to read when there are lots of variables. But direct statements in the constructor body makes it clear what is happening.

Also, I was told that variables in a constructor initialization list must be listed in the order they were declared in the class. Is that true?

The init list allows you to construct variables with particular arguments:

1
2
3
4
5
6
7
8
9
10
11
12
class X {
public:
    //note, no default constructor
    X(int) { /*...*/ }
};

class Y {
    X some_x;
public:
    Y() : some_x(1) {} //ok
    Y() : { some_x = X(1); } //error, can't default construct X
};


This is also the only way to initialize const members to a particular value.

Also, I was told that variables in a constructor initialization list must be listed in the order they were declared in the class. Is that true?


No, they can be in any order.

Apparently you have to...
Last edited on
No, they can be in any order.


My C++98 compiler disagrees. Best practice: just list them in the same order.
Check out this article...it's bring's light to this subject and a great read.
http://www.cprogramming.com/tutorial/initialization-lists-c++.html

The use of it is dictated by what you're doing in OOP. When a class inherits from another class, sometimes you want to use an initialization list. According to Alex Allain (the author of the above article), each class should only have to initialize things that belong to it. Since inheritance is basically the 'borrowing' of another class's functionality, inherited items should be initialized by the owning class. In that case, you may want an initialization list to supply the inherited class with certain data to meet the needs of your program.
Last edited on
Maybe it would be helpful to point out that every member and base is initialized before the opening brace of the constructor. It's impossible to initialize them within the constructor, it's only possible to replace their values with something else, using assignment where permitted.

If you are going to initialize something, might as well do it right the first time.
Consider this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>

int creation_index = 0;

struct item1
{
    item1(void)
    {
        std::cout << "item1: " << creation_index++ << std::endl;
    }
};

struct item2
{
    item2(void)
    {
        std::cout << "item2: " << creation_index++ << std::endl;
    }
};

struct base
{
    item1 m_item1;
    base(void)
    {
        std::cout << "base: " << creation_index++ << std::endl;
    }
};

struct derived : public base
{
    item1 m_item1;
    item2 m_item2;
    derived(void)
    {
        std::cout << "derived: " << creation_index++ << std::endl;
    }
};

int main(void)
{
    derived d;
    return 0;
}


It's output:

item1: 0
base: 1
item1: 2
item2: 3
derived: 4

Member variables are constructed in the order they are listed in the class, and this happens before the class constructor. Base classes are constructed before derived classes.

You will find the reverse order for destruction.

The following is undefined behavior:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>

struct item
{
    int length;
    std::string str;
    
    item(void)
        :str("hello"), length( str.length())
    {
        std::cout << length << std::endl;
    }
};

int main(void)
{
    item i;
}


Where as this works just fine:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>

struct item
{
    std::string str;    
    int length;

    item(void)
        :length( str.length()), str("hello")
    {
        std::cout << length << std::endl;
    }
};

int main(void)
{
    item i;
}


Though I see this is different than what Duoas reports. I only get warnings from -Wreorder

The warning being that length will be initialized after str.
Last edited on
Topic archived. No new replies allowed.