Reputation: 2189
I have the following simple code:
class A
{
int a;
public:
A(int a) : a(a) { cout << "Constructor a=" << a << endl; }
~A() { cout << "Destructor a=" << a << endl; }
void print() { cout << "Print a=" << a << endl; }
};
void f()
{
A a(1);
a.print();
a = A(2);
a.print();
}
int main()
{
f();
return 0;
}
The output is:
Constructor a=1
Print a=1
Constructor a=2
Destructor a=2
Print a=2
Destructor a=2
I find that there are two destructor calls with a=2
and none with a=1
while there is one constructor call for each case. So how are contructors and destructros called in this case?
Upvotes: 6
Views: 725
Reputation: 2092
void f()
{
A a(1); // Constructor a=1 (a.a(1) is called)
a.print(); // Print a=1
a = A(2); // Constructor a=2 (Temporary unnamed object A(2) is constructed)
// compiler generated a.operator=(const A&); is called and then
// Destructor a=2 (Temporary unnamed object is destroyed.
a.print(); // Print a=2
// Destructor a=2 (a.~a() is called)
}
Upvotes: 2
Reputation: 20997
This is because you're not destroying A(1)
you're assigning A(2)
to it, let's extend your example by adding assign operator:
class A
{
int a;
public:
A(int a) : a(a) { cout << "Constructor a=" << a << endl; }
~A() { cout << "Destructor a=" << a << endl; }
void print() { cout << "Print a=" << a << endl; }
A &operator=(const A &other) {
cout << "Assign operator old=" << a << " a=" << other.a << endl;
a = other.a;
}
};
Which will result to:
[vyktor@grepfruit tmp]$ ./a.out
Constructor a=1
Print a=1
Constructor a=2
Assign operator old=1 a=2 <- This line explains why destructor is not called
Destructor a=2
Print a=2
Destructor a=2
If you have one of these implemented:
you should implement all of them. This is called rule of three.
Upvotes: 2
Reputation: 862
First the constructor for a=1 is called
Second the print is called
Third the new object which you created A(2) has its constructor called.
Fourth this object is assigned to object a so data member of object a=2
Fifth the destructor for object A(2) is called
Sixth the destructor for object a is called
Upvotes: 1
Reputation: 4463
a = A(2);
Will use default operator=
to assign new value to a
, setting it's a::a
member value to 2.
void f()
{
A a(1);//a created with int constructor a.a == 1
a.print();// print with a.a == 1
a = A(2);//Another A created with int constructor setting a.a == 2 and immediately assigning that object to a
//object created with A(2) deleted printing 2 it was created with
a.print();//a.a==2 after assign
}//a deleted printing 2 it was assigned with
You probably should read about Rule of three to get better understanding what's going on.
Upvotes: 7
Reputation: 33671
void f()
{
A a(1);
// Constructor a=1
a.print();
// Print a=1
a = A(2);
// Constructor a=2
// also operator=
// Destructor a=2
a.print();
// Print a=2
// Destructor a=2
}
Upvotes: 4