Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the destructor called?

Tags:

c++

destructor

I wrote a simple vector class which overloads assignment and addition operators. The code adds two vectors and prints vectors before and after the addition. Surprisingly destructor ~MyVector() is being called after the line c=a+b. I do not see the reason why is it so, as neither of objects a,b and c gets out of scope. Do you understand the reason for invocation of the destructor?

#include<iostream>
#include<cstdlib>

using namespace std;

template<typename T>
class MyVector
{
  public:

  MyVector(int s)
  {
    size=s;
    a=new T[s];
  }

  ~MyVector()
  {
    delete[] a;
    size=0;
  };

  void freeVec()
  {
    cout<<"Calling destructor. a[0]= "<<a[0]<<endl;
    if(a!=NULL)
    {
      free(a);
      a=NULL;
    }
  }

  int getSize(void)
  {
    return size;
  }
  void setSize(int ss)
  {
    size=ss;
  }
  T &operator[](int i)
  {
    return a[i];
  }

  MyVector &operator=(MyVector mv)
  {
    if(this==&mv)
      return *this;
    for(int i=0;i<mv.getSize();i++)
      this->a[i]=mv[i];
    this->size=mv.getSize();
    return *this;
  }

  MyVector operator+(MyVector &mv)
  {
    for(int i=0;i<size;i++)
    {
      this->a[i]+=mv[i];
    }
    cout<<endl;
    return *this;
  }

  private:
  int size;
  T *a;
};

int main(void)
{
  MyVector<int> a(3),b(3),c(3);

  a[0]=1;a[1]=2;a[2]=3;
  b[0]=4;b[1]=5;b[2]=6;
  cout<<"initial vector"<<endl;
  for(int i=0;i<3;i++)
    cout<<a[i]<<"  ";
  cout<<endl;
  for(int i=0;i<3;i++)
    cout<<b[i]<<"  ";
  cout<<endl;

  c=a+b;  

  cout<<"final vectors"<<endl;
  for(int i=0;i<3;i++)
    cout<<a[i]<<"  ";
  cout<<endl;
  for(int i=0;i<3;i++)
    cout<<b[i]<<"  ";
  cout<<endl;
  for(int i=0;i<3;i++)
    cout<<c[i]<<"  ";
  cout<<endl;

  cout<<endl;
  return 0;
}
like image 750
Igor Popov Avatar asked Feb 03 '26 17:02

Igor Popov


2 Answers

Your a + b returns a nameless temporary object that consequently gets copied to c (by the assignment operator) and then gets destructed. That's the destructor call that you see.

Also, your assignment operator receives it parameter by value (why???), which means that theoretically another copy can be created for that as well. Your compiler apparently optimized out that copy, which is why you see only one additional destructor call.

BTW, since you manually manage allocated memory in your object, it is a very good idea to implement copy constructor as well, in accordance with the "Rule of Three". The current version of the class (without copy constructor) can easily be used to build broken code specifically because the copy constructor is missing. In fact, your current code is already broken, since it uses compiler-provided copy constructor for copying your class object. The only reason you don't see any crashes is because the compiler optimized out (elided) most of the copies and, probably, because you got lucky.

On top of that your implementation of binary + modifies the data stored in *this object (why???), meaning that c = a + b modifies a. This is not exactly what people expect to see as a typical behavior of binary + operator.

There are lots of other bizarre things in your code. For example, what is freeVec and why is it trying to use free on memory that is always allocated by new[]? Also, why does the destructor set size to 0? What is the point of that?

like image 158
AnT Avatar answered Feb 06 '26 06:02

AnT


Because your MyVector operator+(MyVector &mv) creates a copy (as it should do). This temporary copy is destroyed once it has been stored in c.

Note that modifying this in operastor+ is not a great plan. You don't expect a to become the same value as c from c = a + b;.

like image 41
Mats Petersson Avatar answered Feb 06 '26 05:02

Mats Petersson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!