Utsav
Utsav

Reputation: 566

Unexpected call to destructor in C++

Kindly consider the following piece code.

#include<iostream>

using namespace std;

class A
{
private:
  int *x;
public:
  A(int a)
  {
    cout<<"creating "<<a<<" "<<this<<endl;
    x = new int;
    *x = a;
  }

  A(A *a)
  {
    this->x = a->x;
  }

  ~A()
  {
    cout<<"destroying "<<x<<endl;
    delete x;
  }

  A *operator+(A a)
  {
    return new A(*x + *(a.x));
  }

  void display()
  {
    cout<<*x<<endl;
  }
};

int main()
{
  A a(5);
  A b(10);
  A c = a + b;

  cout<<"control returns to main"<<endl;
  a.display();
  b.display();
  c.display();
  return 0;
}

It produces the following output.

creating 5 0xbffd6710
creating 10 0xbffd6714
creating 15 0x9273028
destroying 0x9273018
control returns to main
5
0
15
destroying 0x9273038
destroying 0x9273018
destroying 0x9273008

I can't understand why was the destructor invoked prior to when the control was returned to the main function. Even more importantly why was it called on b? If it was called on the new object returned by operator+ it would have been understandable as destructors are called when the control comes out of the scope of the object.

Upvotes: 0

Views: 568

Answers (3)

Remy Lebeau
Remy Lebeau

Reputation: 598011

Your implementation of the copy constructor and + operator are wrong. Try this instead:

class A
{
private:
  int *x;
public:
  A(int a)
  {
    cout << "creating " << a << " " << this << endl;
    x = new int;
    *x = a;
  }

  A(const A &a)
  {
    cout << "copying " << *(a.x) << " " << this << endl;
    x = new int;
    *x = *(a.x);
  }

  ~A()
  {
    cout << "destroying " << *x << " " << this << endl;
    delete x;
  }

  A operator+(const A &a)
  {
    return A(*x + *(a.x));
  }

  void display()
  {
    cout << *x << endl;
  }
};

Upvotes: 0

user995502
user995502

Reputation:

A *operator+(A a)
  {

Receives by value. Which means when

a + b;

is encountered a new copy of b is created and passed to operator+(A a)

You dont see a new one constructed because you don't have a copy constructor implemented and the compiler created it for you. Otherwise you will see one more A being created.

If you instead make your operator* take a reference like this

  A *operator+(A& a)
  {
    return new A(*x + *(a.x));
  }

You won't see the destruction anymore because no copy is created.

Upvotes: 7

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385395

You:

  • don't output "creating" (or, indeed, handle your resources properly) for the copy constructor (which at the moment is compiler-generated)

  • are seeing the temporary a + b get destroyed

Upvotes: 2

Related Questions