4

Assume T is a C++ class, and if I do T a = b;, is the copy constructor or assignment operator called?

My current experiment shows the copy constructor is called, but do not understand why.

#include <iostream>
using namespace std;

class T {
 public:
  // Default constructor.
  T() : x("Default constructor") { }
  // Copy constructor.
  T(const T&) : x("Copy constructor") { }
  // Assignment operator.
  T& operator=(const T&) { x = "Assignment operator"; }
  string x;
};

int main() {
  T a;
  T b = a;
  cout << "T b = a; " << b.x << "\n";
  b = a;
  cout << "b = a; " << b.x << "\n";
  return 0;
}

$ g++ test.cc
$ ./a.out
T b = a; Copy constructor
b = a; Assignment operator

Thanks!

Ying Xiong
  • 4,578
  • 8
  • 33
  • 69
  • 2
    In `T b = a` you are creating (constructing) an object named b, no such object existed before so one must be constructed, hence the use of a constructor. In `b = a`, an object named b already exists and you are replacing (assigning) its previous values with values copied from a, so an assignment operator is used. – YoungJohn Nov 13 '14 at 21:15
  • `but do not understand why.` Is there any reason you think the behavior should be different? –  Nov 13 '14 at 21:16
  • Related: http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization – R Sahu Nov 13 '14 at 21:17
  • 1
    @remyabel naively, since an equals sign is present, one might expect `T b = a` to default-construct a `T` and then call `operator=(a)` on it. I assume this is the less performant alternative 40two alluded to below. – dlf Nov 13 '14 at 21:18
  • There's no way that this isn't a duplicate of, like, fifty existing questions on SO. – user541686 Nov 17 '14 at 09:29

2 Answers2

6

The copy constructor is called because

T a = b;

has the same effect as

T a(b);

It's an initialization, not an assignment. Long story short, it's just how the language works.

bstamour
  • 7,746
  • 1
  • 26
  • 39
  • 6
    these two lines are not *the same* – Piotr Skotnicki Nov 13 '14 at 21:07
  • 1
    It's not a long story it's for performance, plus I agree with @PiotrS. – 101010 Nov 13 '14 at 21:08
  • 6
    The first one is [copy initialization](http://en.cppreference.com/w/cpp/language/copy_initialization). The second one is [direct initialization](http://en.cppreference.com/w/cpp/language/direct_initialization). I think the OP is asking about assignment vs initialization. –  Nov 13 '14 at 21:09
2
...

// The variable a does not exist before this point, therefore it is *conststructed*
T a = b; // Copy constructor is called

...

vs

...

T a;   // Default constructor is called

// a already exists, so assignment is used here
a = b; // assignment operator is called

...
Julian
  • 1,688
  • 1
  • 12
  • 19