Benefits of Initialization lists

2019-01-01 08:46发布

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;
};

6条回答
萌妹纸的霸气范
2楼-- · 2019-01-01 09:29

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

查看更多
骚的不知所云
3楼-- · 2019-01-01 09:31

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?-)

查看更多
余生无你
4楼-- · 2019-01-01 09:32

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;
}
查看更多
倾城一夜雪
5楼-- · 2019-01-01 09:48

It's a great way to initialize members that :

  • are const
  • don't have a default constructor (it's private)
查看更多
孤独寂梦人
6楼-- · 2019-01-01 09:49

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.

查看更多
无色无味的生活
7楼-- · 2019-01-01 09:52

Below are the scenarios when initializer list is used:

  1. For initialization of non-static const data members.
  2. For initialization of reference members.
  3. For initialization of member objects which do not have default constructor.
  4. For initialization of base class members.
  5. When constructor’s parameter name is same as data member.
  6. For Performance reasons.
查看更多
登录 后发表回答