3
class A {};
class B { public: B (A a) {} };

A a;
B b=a;

Technically speaking, is a copy constructor being applied here on the creation of b ?

Michael
  • 22,196
  • 33
  • 132
  • 187
  • 5
    this is not copy constructor. Copy constructor take same type of object as parameter. – Romil Kumar Jain Jun 27 '12 at 07:25
  • 1
    [Is there a difference in C++ between copy initialization and direct initialization?](http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-direct-initializati). – Jesse Good Jun 27 '12 at 07:43

4 Answers4

14

Yes, in theory. This is copy-initialiation. First a temporary B instance is constructed from the initializer (a), then b is initialized from this temporary via the copy constructor.

Compilers are allowed to, and frequently do, elide the temporary and the copy construction, though, and construct b directly from a using the B(A) constructor.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 1
    +1 only correct answer so far. I also always thought `=`-initialization was equivalent to a corresponding constructor call until I tried to do `std::auto_ptr p = new T;` and didn't get the results I expected. By the way, the respective part in the standard is §8.5 [dcl.init] paragraph 16. – Christian Rau Jun 27 '12 at 08:37
7

Technically speaking, is a copy constructor being applied here on the creation of b ?

Yes...but probably not how you think. A's copy constructor is being invoked on the creation of b, in order to do the pass-by-value of the parameter A a as a parameter to the B constructor.

However, it is not running B's copy constructor in the creation of b.


EDIT: One learns something new every day. Apparently even more-technically-speaking, as @CharlesBailey pointed out...if you use the B b = a; syntax ("copy initialization") instead of B b (a); syntax ("direct initialization"), a temporary value of type B might need to be created. At this point B's copy constructor would wind up being called.

It's a little hard to study the phenomenon, but Charles points out that gcc has a -fno-elide-constructors option (also: Wikipedia on Copy Elision) @JesseGood's link has an exhaustive explanation and some demonstration code:

Is there a difference in C++ between copy initialization and direct initialization?

Community
  • 1
  • 1
  • 3
    Technically `B b = a;` is equivalent to `B b(B(a))`, so `B`'s implicitly created copy constructor is called too. :) – GManNickG Jun 27 '12 at 07:35
  • 2
    @GManNickG I don't see why, seeing how B has a conversion constructor from A directly... – Luchian Grigore Jun 27 '12 at 07:36
  • @GManNickG Really? I always thought `B b = a;` was transformed to `B b (a);` and I was just being weird by not wanting to have an `=` sign in my initializers, ever (so one wouldn't think overloaded assignment would be applicable there). If what you say is true, that would be an even better reason to use the parenthetical form, always! – HostileFork says dont trust SE Jun 27 '12 at 07:37
  • They're not technically equivalent. – Luchian Grigore Jun 27 '12 at 07:38
  • 2
    If a constructor is `explicit`, you can't use `=` in initialization. – Luchian Grigore Jun 27 '12 at 07:40
  • 2
    @HostileFork: Copy initialization where the initializer is not of the same type as the object being initialized and the type being initialized isn't a reference type requires the initializer to be converted to a temporary of the correct type which is then used to direct-initialize the object being constructed. The compiler is allowed to eliminate the temporary and the copy (or move) and reduce it to a simple direct initialization if this is possible, but it doesn't have to. – CB Bailey Jun 27 '12 at 08:09
  • @LuchianGrigore: Syntactically `T x = a;` is copy-initialization so initializes a copy of `T` made from `a`, in this case `b` is initialized from a temporary `B` made from `a`. Any compiler will of course remove the copy and directly initialize it, *but it must make sure the copy-constructor (or move-constructor) is actually accessible to do this*! In other words, this shouldn't compile: `noncopyable x = a;`, but MSVC compiles it anyway (reducing it to `noncopyable x(a)`). I don't know if it is fixed in VS12. – GManNickG Jun 27 '12 at 08:27
  • @HostileFork: In practice `T x = a;` almost always reduces to `T x(a)` anyway, *due to optimization*, but language-wise they are indeed different. – GManNickG Jun 27 '12 at 08:29
  • gcc's `-fno-elide-constructors` can be quite instructive. – CB Bailey Jun 27 '12 at 08:34
3

No, a copy constructor takes a reference to an object of the same kind.

C++03 12.1 Constructors

  1. A copy constructor for a class X is a constructor with a first parameter of type X& or const X&.

EDIT: OK, to be fair (and after reading the other answers), a copy constructor is being called, but it's A's copy constructor. I thought you meant B's.

EDIT2: To be fairer, it's not necessary for it to be called at all:

A a;
B b = a;   //called
B c = A(); //probably not called due to copy elision
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 1
    Post edit: Technically both `A` and `B`'s copy constructors get called. When converting `a` to a `B` the copy constructor for `A` will be called to construct the by-value parameter for `B(A)`, then `B`'s copy constructor will be called to construct `b` from the temporary `B` constructed from `a`. – CB Bailey Jun 27 '12 at 08:00
  • @CharlesBailey what? wow didn't know that. What if we had `B (A& a)` instead? – Luchian Grigore Jun 27 '12 at 08:02
  • Then `a` binds directly to the reference parameter of `B(A&)` (it is not permitted to copy `a`) and only `B`'s copy constructor is called. – CB Bailey Jun 27 '12 at 08:05
  • @CharlesBailey but why? You already have an `A` object, why not directly create a `B` from it, but from an intermediary `B`?... – Luchian Grigore Jun 27 '12 at 08:06
  • Those are the rules. But consider the case when the conversion from `A` to `B` was supplied by a conversion operator on `A`, not a converting constructor of `B`. – CB Bailey Jun 27 '12 at 08:12
  • @CharlesBailey ah sorry, I also tried this - http://ideone.com/dBlZ7 - but I have to say I don't fully understand. – Luchian Grigore Jun 27 '12 at 08:17
  • @LuchianGrigore See the standard §8.5 [dcl.init] paragraph 16, though it is a weird rule and has bitten me more than once so far. – Christian Rau Jun 27 '12 at 08:39
  • @ChristianRau got it - http://stackoverflow.com/questions/11222076/why-is-copy-constructor-called-instead-of-conversion-constructor/11222105#11222105 – Luchian Grigore Jun 27 '12 at 08:45
0

No. It's not a Copy Constructor.

If you creates an object by initializing it with an object of the same class, that is copy constructor.

A a;
A b=a;

The above code is copy Constructor.

Kalai Selvan Ravi
  • 2,846
  • 2
  • 16
  • 28