开发者

Why does data get assigned without an extra copy being created, in an initialization list?

Parashift explains initialization lists w开发者_StackOverflowell, but does not explain why an extra copy of a variable is created before assignment in the ctor body, but no extra copy is created when assigned through an initialization list.

I've even come across advice of using ++i instead of i++ because the former avoids creation of a temporary i before assignment. Is it the same for POD's assigned in a ctor body? A temp variable gets created before the assignment happens?

To put it another way, why does the compiler need to create an extra copy of a variable? Why can't it just assign the variable directly?

Why?


Consider the following:

struct C { 
    C() { /* construct the object */ }
};

struct X {
    C member;

    X() { member = C(); }
};

The X() constructor is the same as if you had said:

X() : member() { member = C(); }

First, the C constructor is called to construct the member data member. Then the body of X is executed, a second, temporary C object is created and assigned to member, then the temporary is destroyed.


Note that this is only the case for types that are initialized automatically. If member was of type int or of a POD class type (as examples), it would be uninitalized when the body of the X constructor is entered.

For such types it doesn't really matter from a performance standpoint whether you initialize the data member in the initialization list or assign to the data member in the body of the constructor; the difference is entirely stylistic. Where possible, the initialization list should still be preferred for the sake of consistency.


To address your first question specifically regarding the copy (without touching on "++i" vs "i++"):

The constructor is a function, and it has parameters. These parameters are copies of the variables passed as parameters (unless passing by reference is used). You can now manipulate this copy or do anything else with it. Then when you assign, you take this copy of the parameter (possibility manipulated) and assign it to the member variable. When you use an initialization list, the compiler can optimize the assignment immediately without this copy, as you will not be using it for anything but the initialization (and cannot modify it before assigning it to the member variable).


why an extra copy of a variable is created before assignment in the ctor body, but no extra copy is created when assigned through an initialization list.

Because assignment follows initialization. In other words, assignment is optional, but initialization is mandatory. You may not notice much difference for PODs. But the same holds true for user defined data types.

advice of using ++i instead of i++

Again for PODs it doesn't matter much. But for user defined classes, i++ does create a temporary copy. So it's better to use ++i.

struct A {
  A operator ++ (int)  // example of i++
  {
    A temp = *this;
    this->value ++;
    return temp;    // makes 2 copies "temp" and return value
  }
  A& operator ++ ()  // example of ++i
  {
    this->value ++;
    return *this;  // no copy
  }
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜