1
#include<iostream>
using namespace std ; 
class Foo{
    int a , b ;
public:
    Foo(int x, int y){
        a = x ;
        b = y  ;
    }
    Foo(Foo& obj){
        a = obj.a ;
        b = obj.b ;
    }
};

int main(){
    Foo obj(2,3) ;
    Foo obj1(obj) ;
    Foo obj2 = obj ;
}

If I am right, both Foo obj2 = obj ; and Foo obj1(obj) ; call the copy constructor.

What are the pros and cons of using one over the other ?

Tasdik Rahman
  • 2,160
  • 1
  • 25
  • 37
  • 3
    `Foo obj1(obj);` is direct initialization, `Foo obj2 = obj;` is copy-initialization. The primary difference here is that the first can call `explicit` constructors while the second cannot, but no sane person would make the copy constructor explicit. – T.C. Sep 14 '14 at 11:55
  • http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-direct-initializati – Ashalynd Sep 14 '14 at 12:00
  • Any particular reasons for that @T.C.? Just curious. – Tasdik Rahman Sep 14 '14 at 12:01

1 Answers1

5

Foo obj1(obj); is direct initialization, Foo obj2 = obj; is copy-initialization.

The only difference here is that the first can call explicit constructors while the second cannot.

However, no sane person would make the copy constructor explicit, so assuming that you are working with sane code it should make no difference. A class with an explicit copy constructor doesn't satisfy CopyConstructible requirements (required for a number of standard container operations). Both function return and argument passing uses copy-initialization, so a class with an explicit copy constructor would not be usable in those contexts.


Just to make things crystal clear. N3936 §8.5 [dcl.init]/p15-16:

15 The initialization that occurs in the form

T x = a;

as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization. [ Note: Copy-initialization may invoke a move (12.8). —end note ]

16 The initialization that occurs in the forms

T x(a);
T x{a};

as well as in new expressions (5.3.4), static_cast expressions (5.2.9), functional notation type conversions (5.2.3), and base and member initializers (12.6.2) is called direct-initialization.

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • 3
    @PaulEvans The only thing wrong here is your claim that `Foo obj1(obj);` is copy-initialization. Pasting a woefully formatted excerpt from the standard which you've *completely misread* doesn't change that fact. – T.C. Sep 14 '14 at 12:11
  • `obj1(obj)` *isn't* direct initialization if `obj` is the same type as, or is derived from the, `obj1` – Paul Evans Sep 14 '14 at 12:17
  • @PaulEvans Did you think somehow "if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination" magically makes direct initialization into copy initialization? It does not. That paragraph specifies that all direct initializations and those particular cases of copy initializations have about the same semantics (save for the candidate constructors considered during overload resolution). – T.C. Sep 14 '14 at 12:23
  • @T.C. I *did* think that, yes... thanks for shining light on a blind spot. – Paul Evans Sep 14 '14 at 12:39