67

If I override operator= will the copy constructor automatically use the new operator? Similarly, if I define a copy constructor, will operator= automatically 'inherit' the behavior from the copy constructor?

2

6 Answers 6

57

No, they are different operators.

The copy constructor is for creating a new object. It copies an existing object to a newly constructed object.The copy constructor is used to initialize a new instance from an old instance. It is not necessarily called when passing variables by value into functions or as return values out of functions.

The assignment operator is to deal with an already existing object. The assignment operator is used to change an existing instance to have the same values as the rvalue, which means that the instance has to be destroyed and re-initialized if it has internal dynamic memory.

Useful link :

Sign up to request clarification or add additional context in comments.

3 Comments

@Prasoon, I don't quite understand, when passing variables by value into functions or as return values out of functions, why copy-constructor might not be called? And what's RVO?
@Alcottreturn value optimization
There is also copy elision, which does the same for function parameters
13

No. Unless you define a copy ctor, a default will be generated (if needed). Unless you define an operator=, a default will be generated (if needed). They do not use each other, and you can change them independently.

Comments

7

No. They are different objects.

If your concern is code duplication between copy constructor and assignment operator, consider the following idiom, named copy and swap :

struct MyClass { MyClass(const MyClass&); // Implement copy logic here void swap(MyClass&) throw(); // Implement a lightweight swap here (eg. swap pointers) MyClass& operator=(MyClass x) { x.swap(*this); return *this; } }; 

This way, the operator= will use the copy constructor to build a new object, which will get exchanged with *this and released (with the old this inside) at function exit.

4 Comments

by referring to the copy-and-swap idiom, do you imply that it's not a good practice to call operator= in copy-ctor or vice versa?
@Alcott: You don't call the operator= in the copy constructor, you do it the other way around, like I show.
Why is your assignment operator not taking a const reference ?
@JohanBoule: This is explained in the wikipedia link in my answer, and also in this question
1

No.

And definitely have a look at the rule of three (or rule of five when taking rvalues into account)

Comments

1

Consider the following C++ program.
Note: My "Vector" class not the one from the standard library.
My "Vector" class interface:

#include <iostream> class Vector { private: double* elem; // elem points to an array of sz doubles int sz; public: Vector(int s); // constructor: acquire resources ~Vector() { delete[] elem; } // destructor: release resources Vector(const Vector& a); // copy constructor Vector& operator=(const Vector& a); // copy assignment operator double& operator[](int i){ return elem[i]; }; int size() const {return sz;}; }; 

My "Vector" class members implementation:

Vector::Vector(int s) // non-default constructor { std::cout << "non-default constructor"<<std::endl; elem = {new double[s]}; sz =s; for (int i=0; i!=s; ++i) // initialize elements elem[i]=0; } Vector::Vector(const Vector& a) // copy constructor :elem{new double[a.sz]}, sz{a.sz} { std::cout << "copy constructor"<<std::endl; for (int i=0; i!=sz; ++i) // copy elements elem[i] = a.elem[i]; } Vector& Vector::operator=(const Vector& a) // copy assignment operator { std::cout << "copy assignment operator"<<std::endl; double* p = new double[a.sz]; for (int i=0; i!=a.sz; ++i) p[i] = a.elem[i]; delete[] elem; // delete old elements elem = p; sz = a.sz; return *this; } int main(){ Vector v1(1); v1[0] = 1024; // call non-default constructor Vector v2 = v1; // call copy constructor !!!! v2[0] = 1025; std::cout << "v2[0]=" << v2[0] << std::endl; Vector v3{10}; // call non-default constructor std::cout << "v3[0]=" << v3[0] << std::endl; v3 = v2; // call copy assignment operator !!!! std::cout << "v3[0]=" << v3[0] << std::endl; } 

Then, the program output:

non-default constructor copy constructor v2[0]=1025 non-default constructor v3[0]=0 copy assignment operator v3[0]=1025 

To wrap up:

  1. Vector v2 = v1; lead to call copy constructor.
  2. v3 = v2; lead to call copy assignment operator.

In case 2, Object v3 already exists (We have done: Vector v3{10};). There are two obvious differences between copy constructor and copy assignment operator.

  • copy constructor NO NEED to delete old elements, it just copy construct a new object. (as it Vector v2)
  • copy constructor NO NEED to return the this pointer.(Furthermore, all the constructor does not return a value).

Comments

0

No, they are not the same operator.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.