Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should you use direct initialization and when copy initialization?

Is it simply preference or are there specific instances where one is necessary over another? I'm refering to the following variants for initialization

T t(e); // direct initialization
T t = e; // copy initialization
like image 726
Mike Avatar asked Nov 27 '10 19:11

Mike


People also ask

What is the difference between copy assignment and copy initialization?

Comparison ChartThe copy constructor initializes the new object with an already existing object. The assignment operator assigns the value of one object to another object both of which are already in existence. (1)Copy constructor invokes when a new object is initialized with existing one.

What is direct initialization?

Direct Initialization or Assignment Operator (Syntax) This assigns the value of one object to another object both of which are already exists. Copy initialization is used when a new object is created with some existing object. This is used when we want to assign existing object to new object.

What is the difference between initializing and assigning?

What is the difference between initialization and assignment? Initialization gives a variable an initial value at the point when it is created. Assignment gives a variable a value at some point after the variable is created.

How does initialization work?

Initialization is the process of locating and using the defined values for variable data that is used by a computer program. For example, an operating system or application program is installed with default or user-specified values that determine certain aspects of how the system or program is to function.


2 Answers

The actual names of the things you describe is not implicit and explicit assignment but :

  • Copy-initialization : T x = a;
  • Direct-initialization : T x(a);

They are not equivalent, most notably in contexts where a conversion is required, for example when T is of class type and a is of a different type (see Alf comment for examples of contexts which don't even involve conversion). Consider the following code :

class Test
{
public:
    explicit Test(int i) { /* ... */ }
};

int main()
{
    Test t(0);  // OK : calls Test::Test(int)
    Test u = 0; // KO : constructor is marked explicit
}

To paraphrase the standard (8.5/14) :

  • For direct-initialization and copy-initialization where the source type is the same as, or a derived class of, the class of destination, constructors are considered
  • For other copy-initialization cases, like the second line of main in my example, user-defined conversion sequence are considered. As the use of the Test constructor for implicit conversion was disallowed by the explicit keyword, the second line fails to compile.
like image 60
icecrime Avatar answered Oct 04 '22 02:10

icecrime


Direct initialization like

std::istringstream  stream( "blah blah" );

is necessary when the type in question, here std::istringstream from the C++ standard library, does not have an accessible copy constructor.

A copy initialization, like

std::istringstream  stream = "blah blah";   //! NOT VALID

requires an accessible copy constructor, because it's performed as if a temporary object is created on the right hand side of =, and as if that temporary is then used to initialize the variable being declared.

In the other direction, in C++98 the copy initialization syntax is needed in order to use curly braces initializers. For example, direct initialization can't be used to initialize an aggregate. But you can use copy initialization with a curly braces initializer:

#include <string>
using namespace std;

struct Answer
{
    int     nVotes;
    string  description;
};    

int main()
{
    Answer const  incorrect   = { 26, "they're the same!" };
    Answer const  correct     = { -1, "nah, they're different, actually" };
}

So, there are significant differences.

I generally prefer copy initialization syntax because of the clarity. But sometimes, as shown above, direct initialization is, unfortunately, necessary. Some people, e.g. C++ textbook author Francis Glassborow, have instead landed on direct initialization as their preferred initialization syntax (I'm not sure why, it's less clear to my eyes, and introduces the "most vexing parse" problem), and for them it's the necessity of copy initialization in some cases, that is unfortunate.

Cheers & hth.,

like image 36
Cheers and hth. - Alf Avatar answered Oct 04 '22 03:10

Cheers and hth. - Alf