wds
wds

Reputation: 61

Initialising class members - default values or member-init-list?

I'm a bit confused about when and how to initialize members of a class in a constructor. If I understand things correctly, you can accomplish this by either including default values in the class definition, a constructor member initialiser list, or via assignment in the body of the constructor. I realise that it's best to initialize before entering the body of the constructor, but when should you use a member initialiser list and when should you use default values?

Apologies if I've fundamentally misunderstood something here.

Upvotes: 2

Views: 545

Answers (1)

Wolf
Wolf

Reputation: 10238

Your are really confusing things a bit. There are at least 4 different concepts

you made 3 of.

In the following examples (at ideone.com) I use struct instead of class and inline constructors for brevity/simplicitly.

#include <iostream>

struct A 
{ 
    A(int v=1): m(v) {}
    int m; 
};

struct B
{ 
    B(): m(2) {}
    int m; 
};

struct C
{ 
    C()
    {
        m = 3;
    }
    int m; 
};

// since C++11
struct D
{ 
    int m = 11; 
};

int main()
{
    using namespace std;
    #define TRACE(arg) cout << #arg ": " << arg.m << endl; 
    A a1;
    TRACE(a1)
    A a2(4); 
    TRACE(a2)
    B b;
    TRACE(b)
    b.m = 5;
    TRACE(b)
    C c;
    TRACE(c)
    c.m = 6;
    TRACE(c)
    D d;
    TRACE(d)
    d.m = 0;
    TRACE(d)
    #undef TRACE
}

The usage of A differs from that of B, C and D.

Only A provides a way to initialize m with a value other than the default. All variants provide direct access to m (mostly not a good choice, see it as a placeholder for a more sophisticated way to modify a member). You have to modify an object if there is no access to the actual initializer value(s). This makes m for constant objects of B, C and D effectively a compile-time constant. Member "initialization" in the constuctor body (C) should be avoided if an initializer list (A or B) can be used (sometimes this is not as trivial as shown here).

Option D should be estimated if you are using C++11 or later.

So A seems the most flexible option. But it's not a good pattern for initializing two or more members: it's too easy to mix up the parameter order.


[1] this option was added after I (thanks to NikosC) realized that this options existed

Upvotes: 2

Related Questions