5

Possible Duplicate:
Is there a difference in C++ between copy initialization and direct initialization?
Copy constructors and Assignment Operators

I have a class C in which I have overloaded Normal, copy constructor and assignment operator to print a trace of what is being called..

I wrote following pieces of code to test what is being called when?

C c1;                --> Normal Constuctor .. // understood Fine

C c2;
c2 = c1;             --> Normal constructor + assignment operator .. //understood Fine

C * c3 = new C(C1)   --> Copy constructor  // Understood Fine

C c4 = c1          --> copy constructor // Not Able to understand

This seems to baffle me since in this code though I am initializing at the time of declaration, it is through assignment operator and not copy constructor .. Am I understanding it wrong ??

Community
  • 1
  • 1
Anerudhan Gopal
  • 379
  • 4
  • 13

3 Answers3

16

Because C c4 = c1; is syntactically semantically equivalent to:

C c4(c1);

Both would invoke copy constructor in this particular case. However there is a subtle difference between "copy initialization" (1st syntax) and "direct initialization" (2nd syntax). Look at this answer.

Note: In "layman's terms", a variable (here c4) is constructed till the first ; (or ,' for multiple objects) is encountered; Till then everything is one or the other type of constructor.

In case of C c4 = c1;, compiler doesn't have to check for most vexing parse.
However one can disable C c4 = c1; kind of syntax by declaring copy constructor explicit. For that matter any constructor can be made explicit and you can prevent = sign in the construction.

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Yeah.. that was my actual doubt .. Why C c4 = c1; is syntactically equivalent to C c4(C1) and not C C4; c4 = c1; Why was it made that way..? – Anerudhan Gopal May 15 '12 at 06:49
  • @AnerudhanGopal because that's just the way it is (and maybe for the reason that the former is more efficient). – Seth Carnegie May 15 '12 at 06:50
  • @AnerudhanGopal, in c++ for many constructs there are multiple syntax. this is one of them. I have edited my answer for more details. – iammilind May 15 '12 at 06:59
  • Can you please ellaborate more on *"In case of `C c4 = c1;` compiler doesn't have to check for most vexing parse, so I believe it's a superior syntax compared to `C c4(c1);` on compiler perspective.*" How is it superior at run-time? Or are you talking of superiority in terms of compilation time? – Alok Save May 15 '12 at 07:07
  • @Als, I already edited answer. It was meant for compilation time. Though mostly it will be true, but may not be always. I have linked the answer from your post. – iammilind May 15 '12 at 07:08
  • 1
    The first part of the answer is still misleading which states, *`C c4 = c1;` is syntactically equivalent to: `C c4(c1);`*, It is not! They might behave similarly *sometimes* but they are definitely not the same. – Alok Save May 15 '12 at 07:11
  • @Als, for the same object types, they will **always** behave in same way. The behavior would differ only when the source object and destination objects are different. The asker wanted a localize answer specific to the question. – iammilind May 15 '12 at 07:17
  • Yes, and So I said *misleading* not *Incorrect*, this scenario is one of those *sometimes* where they behave exactly same, the answer doesn't clarify that and so is misleading.Of-course, I didn't downvote your answer for that & I could only demonstrate that by adding an downvote(if you would like me to prove so). – Alok Save May 15 '12 at 07:20
  • 3
    I have several problems with this answer. The first is purely linguistic: `C c4 = c1;` is clearly _not_ syntactically equivalent to `C c4( c1 );`. You probably meant to say semantically equivalent, which is only true if the initializing expression (`c1` in this case) has the same type as the new object. And finally, `c4` is fully constructed at the end of the declarator, which may be before the `;`, if you define two variables in the same statement: `C c4 = c1, c5 = c4;`. (Bad practice, IMHO, but perfectly legal.) – James Kanze May 15 '12 at 07:53
  • @JamesKanze, you have taken the wrong meaning of `c4 is fully constructed` part. I had already mentioned it's in "layman" language. The meaning of the sentence was that, only a constructor can appear for a variable until it encounters its 1st `;`. Anyways, I din't expect to explain this in detail. :) – iammilind May 15 '12 at 08:03
8
C c4 = c1;

is Copy Initialization.

It tries to convert c1 to an type C if it is already of not that type by finding a suitable conversion function and then uses the the created C instance for copy constructing a new C instance.

Note that though,

C c4(c1);

is Direct Initialization

And it is important to note that there is a difference between Copy Initialization and Direct Initialization they are not the same!

Why C c4 = c1; is syntactically equivalent to C c4(C1) and not C C4; c4 = c1; Why was it made that way?
First, Copy Initialization & Direct Initialization are not the same.
As to the rationale of why no assignment operator is called, assignment only occurs when one assigns two completely formed objects to each other.

In case of:

C c4 = c1;

c1 is a completely constructed object while c4 yet does not exist all, When such an scenario arises and = is present, it doesn't really mean Assignment but it means Initialization.
So Basically, what happens here is Initialization and not Assignment and the C++ Standard defines specific rules as to how this initialization should be done.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
1

Because there's no assignment operator in:

C c4 = c1;

Like the comma, the equal sign can be either an operator or punctuation. In an expression, it is always an operator, but in the above, the initialization expression is simply c1; the = sign is punctuation, indicating that copy initialization, rather than direct initialization, is to be used. (Direct initialization would be

C c4( c1 );

and is, IMHO, generally preferable. In the case where the initialization expression has the same type as the new object, however, there is no difference.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329