Reputation: 273
#include <iostream>
using namespace std;
class t{
private:
int * arr;
public:
t() { arr=new int[1]; arr[0]=1;}
t(int x) {arr=new int[1]; arr[0]=x;}
t(const t &);
~t() {cout<<arr[0]<<" de"<<endl; delete [] arr;}
t & operator=(const t & t1){arr[0]=t1.arr[0];return *this;}
void print(){cout<<arr[0]<<endl;}
};
t::t(const t & t1) {arr=new int[1];arr[0]=t1.arr[0];}
int main(){
t b=5;
cout<<"hello"<<endl;
b.print();
b=3;
b.print();
return 0;
}
Why the result is
hello
5
3 de
3
3 de ?
why "t b=5;" will not call the destructor? how "t b=5" works? does it create a temp object (of class t) using constructor "t(int x)" first, then use copy constructor "t(const t &)" to create b? if it is the case why it does not call the desctructor for the temp object?
Upvotes: 0
Views: 142
Reputation: 227390
why "t b=5;" will not call the destructor?
When you do this:
t b=5;
you get copy initialization. Semantically, the implicit converting constructor t(int)
is called, and then the copy constructor t(const t&)
is called to instantiate b
. However, the compiler is allowed to elide the copy, which is what is happening in your case. The object is constructed in place, without need for a copy construction. This is why you do not see a destructor call. But your class still needs a copy constructor for that code to compile: copy elision is optional, and whether some code compiles should not depend on whether the compiler is performing an elision or not.
If you had said
t b(5);
then there would be a direct initialization, with no copy elision, and with only one constructor call. Your class would not require a copy constructor in for this code to compile.
Upvotes: 2
Reputation: 10655
Maybe a little trace from your program help you understand what is happing:
int main(){
t b=5; // as you expected, this call the constructor of your object.
cout<<"hello"<<endl;
b.print(); // as you could see, this call print() and print 5
b=3; // this is where the confusion begins. You didn't provide a way
// from your object to make an assigment from an integer, but you
// provide a way to construct an object from integer. So, your
// compiler will construct a temporary object, with 3 as parameter
// and use this object to do this assignment. Once this is a
// temporary object, it will be destructed at the end of this
// operation. That is why you are getting the message: 3 de
b.print(); // print 3 as expected
return 0; // call the destruct from the object that was assigned before
}
Upvotes: 0
Reputation: 52471
Since you don't have an assignment operator taking an int
, b = 3;
is interpreted as
`b.operator=(t(3));`
This creates a temporary t
instance, and destroys it once the assignment returns. That's what prints the first de
line. Finally, at the end of main
, b
goes out of scope, its destructor is called and prints the second line.
Upvotes: 1