52

Of what I know of benefits of using initialization list is that they provide efficiency when initializing class members which are not build-in. For example,

Fred::Fred() : x_(whatever) { }

is preferable to,

Fred::Fred() { x_ = whatever; }

if x is an object of a custom class. Other than that, this style is used even with built-in types for the sake of consistency.

The most common benefit of doing this is improved performance. 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.

With the other style, 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.

Question
Is there any efficiency gain in the following example with using initialization list. I think there is no gain. The first version calls string's copy constructor and the other calls string's assignment operator (there isn't any temporary thats created). It that correct?

class MyClass { public: MyClass(string n):name(n) { } private: string name; }; class MyClass { public: MyClass(string n) { name=n; } private: string name; }; 
4
  • 17
    The other benefit of initialization lists (if you want to a call it a benefit) is that they're the only way to initialize certain things - base classes using a non-default ctor, const members and reference members. Commented Oct 21, 2009 at 6:12
  • 8
    Also, if you are worried about performance, I would rather used a 'const&' to pass the argument, instead of copying. Commented Oct 21, 2009 at 6:36
  • 1
    How can you have Fred::Fred() : x_(whatever)? Fred takes no arguments. Commented Jun 26, 2016 at 14:32
  • it is very easy to see in visual studio 2017 professional edition 'memory view' the memory addresses looks different and thus falsify all wrong assumptions here. In fact, I came to understand that the true purpose of class initialization list is for the const and not about speed. Commented Jul 18, 2018 at 21:15

5 Answers 5

39

The second version is calling string's default ctor and then string's copy-assignment operator -- there could definitely be (minor) efficiency losses compared to the first one, which directly calls c's copy-ctor (e.g., depending on string's implementation, there might be useless allocation-then-release of some tiny structure). Why not just always use the right way?-)

Sign up to request clarification or add additional context in comments.

4 Comments

True. You should also mention that sometimes, "the right way" is the only option you have. If you need to initialize a reference or a const type, or something which doesn't have an assignment operator, you don't have much choice in the matter
@jalf true, but not directly applicable to the code the OP gives (only to variants using e.g. string& members instead of string ones).
Don't you mean it's calling string's copy constructor, and then its assignment operator?
This should not be the accepted answer. The primary purpose for class initialization list is mainly for the const and wither it is about speed is only accidental.
21

I think the only way to initialize const data members is in the initialization list

Eg. in the header:

class C { C(); private: const int x; int y; } 

And the in the cpp file:

C::C() : x( 10 ), y( 10 ) { x = 20; // fails y = 20; } 

1 Comment

This should be the accepted answer. The const usage here clearly and without doubt the primary unambiguous crystal clear usage that only works when inside a class initialization list.
14

Remember that there is a distinct difference between a copy constructor and an assignment operator:

  • the copy ctor constructs a new object using some other instance as a place to get initialization information from.
  • the assignment operator modifies an already existing object that has already been fully constructed (even if it's only by using a default constructor)

So in your second example, some work has already been done to create name by the time that

 name=n; 

is reached.

However, it's quite possible (especially in this simple example) that the work done is vanishingly small (probably just zeroing out some data members in the string object) and that the work is optimized away altogether in an optimized build. but it's still considered good form to use initializer lists whenever possible.

1 Comment

Very well said. While this is basic, this is something that is very easy to overlook/forget for someone like myself who learned on C and assembly.
14

It's a great way to initialize members that :

  • are const
  • don't have a default constructor (it's private)

Comments

2

We can also perform the constructor delegation via the initialization list.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.