The copy constructor and assignment operator
Asked Answered
D

6

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?

Decarbonate answered 20/3, 2011 at 11:41 Comment(2)
Look at the this links : #1458342 & #1477645Effector
possible duplicate of What is The Rule of Three?Credulity
E
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 :

Effector answered 20/3, 2011 at 11:45 Comment(3)
@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?Nee
@Alcottreturn value optimizationLeath
There is also copy elision, which does the same for function parametersDislocation
P
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.

Pinnatifid answered 20/3, 2011 at 11:42 Comment(0)
M
6

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.

Medicable answered 20/3, 2011 at 11:52 Comment(4)
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?Nee
@Alcott: You don't call the operator= in the copy constructor, you do it the other way around, like I show.Medicable
Why is your assignment operator not taking a const reference ?Kanazawa
@JohanBoule: This is explained in the wikipedia link in my answer, and also in this questionMedicable
P
1

No.

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

Poss answered 20/3, 2011 at 11:52 Comment(0)
F
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).
Fredfreda answered 11/3, 2021 at 6:23 Comment(0)
I
0

No, they are not the same operator.

Iaria answered 20/3, 2011 at 11:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.