Search code examples
c++constructordestructorassignment-operator

Why is the constructor and the destructor called when assigning a value to an object


I have the following code:

#include <iostream>

using namespace std;

class A{
    int x;
public:
    A(int x =1) : x(x) {cout << "A() ";}
    A(const A& a) {x =a.x; cout << "A(const A&) ";}
    A& operator=(const A& a){cout << "op= "; x=a.x; return *this;}
    ~A(){cout << "~A()";}
    int getX() {return x;}
    void setX(int x){this->x = x;}
};


A g(A a){
    //a = 2;
    cout << "g() ";
    a.setX(3);
    return a;
}

int main()
{
    A a;
    a = 2;

}

I expected to have the following output: A() op= ~A(), but instead the output isA() A() op= ~A() ~A(). It seems a constructor and a destructor are called when I'm assigning the value 2 to the object a. Why are those two called? Is the compiler effectively creating a new A object that has x = 2 and then uses the assignment operator to assign the value to a?


Solution

  • This is because you didn’t declare an assignment operator for your class that would take an int as an argument. Because no such operator exists the compiler needs to use a workaround: It creates a temporary object using the constructor A(int). You can avoid this behavior by making the constructor explicit:

    explicit A(int x_ = 1) : x(x_) { }
    

    After the temporary is constructed it gets copied to ‘a’ using the provided copy constructor for A. Immediately after that, the temporary gets destroyed and invokes its destructor.

    This approach is inefficient. To make it better, you should define an assignment operator for A taking an int as an argument:

    A& operator= (int x_) {
        x = x_;
        return *this;
    }