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
?
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;
}