user2756494
user2756494

Reputation: 273

constructor and copy constructor

#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

Answers (3)

juanchopanza
juanchopanza

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

Amadeus
Amadeus

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

Igor Tandetnik
Igor Tandetnik

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

Related Questions