0

Theoretical doubt here. Reading a book, and given this statement: StringBad metoo = knot; where:

  • StringBad is a class
  • knot is an object of that class

the author says the following regarding copy constructors:

implementations have the option of handling this statement in two steps: using the copy constructor to create a temporary object and then using assignment to copy the values to the new object.That is, initialization always invokes a copy constructor, and forms using the = operator may also invoke an assignment operator.

My implementation do this in one step:

  • Creates the metoo object with the copy constructor, the same as this : StringBad metoo(knot);

I could understand that other implementations could do it in two steps like this:

  • Create a metoo object with the default constructor, like : StringBad metoo;
  • Use the overloaded asignment operator to assign the knot object to the metoo object.

But the author says an initialization always invokes a copy constructor. Is that correct? If so, what are the steps the compiler would follow in some implementations to make it in two steps? I couldn't test it in mine cause, as I said it does it in one step.

Kurospidey
  • 393
  • 1
  • 4
  • 18
  • 2
    `StringBad metoo();` actually declares `metoo` as a function taking no arguments and returning a `StringBad`, you probably meant `StringBad metoo;` or `StringBad metoo{};`. – Mankarse Aug 18 '12 at 12:01
  • Ewww, bad book. There are so many things wrong with the quoted text that it's pointless to start. Find a different book. – Pete Becker Aug 18 '12 at 22:49

1 Answers1

2

The author is wrong. What you have is a declaration statement with copy initialization, and the only way this can be realized is by instantiating a new object via the StringBad(StringBad const &) copy constructor.* The assignment operator will never be called in this situation, and doesn't even need to exist or be accessible.

There is almost no difference between the two variants StringBad metoo = knot; and StringBad metoo(knot);.

*) or the non-const version if that happens to exist and match.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • thanks for that. So the second case I put would never happen in any implementation. All are supposed to handle that statement in one step. I was thinking that one way of doing it in two steps with the copy constructor could be if the compiler copy by swapping, so it would need to create a temporary knot-like object with the copy constructor and after that swap its values with the defaulted metoo. – Kurospidey Aug 18 '12 at 12:10
  • Note that the `StringBad metoo = knot;` syntax performs _copy-initialization_ while the `StringBad metoo(knot);` syntax performs _direct-initialization_. The behaviour of the two happens to be the same in this case because `knot` is a `StringBad`, but in general they can have different behaviour (approximately speaking, _direct-initialization_ can perform explicit conversions, while _copy-initialization_ can only perform implicit conversions). – Mankarse Aug 18 '12 at 12:19
  • @Mankarse: Yes yes, indeed. But this [has](http://stackoverflow.com/a/8194876/596781) [been](http://stackoverflow.com/a/7436146/596781) [discussed](http://stackoverflow.com/a/10864213/596781) [to](http://stackoverflow.com/a/8002122/596781) [death](http://stackoverflow.com/a/12004139/596781) now, hasn't it :-) – Kerrek SB Aug 18 '12 at 12:28
  • @KerrekSB: Hahaha. Indeed it has. – Mankarse Aug 18 '12 at 12:29
  • 1
    @Kurospidey: There's never anything *but* copy constructors in this situation, guaranteed. No magic "swap" member functions or anything. At best, the compiler could make *two* copies, simliar to `StringBad metoo(StringBad(knot))`, but I'm actually not sure if that's allowed. As Mankarse says, in *general* there could be one *conversion* constructor followed by one copy constructor, which would in practice always be elided, but I think initializing from an object of the same type is *not* a conversion. – Kerrek SB Aug 18 '12 at 12:35