# Thread: Why is destructor being called??

1. Wow thank you guys for going through all that trouble. In my Complex class, it all works similarly. It is only my Matrix class that's giving me trouble. In case you want to compare the ostream operator for the Complex class to the Matrix one, here it is:

Code:
```ostream& operator <<(ostream &out, Complex &a)
{
if(a.real != 0)
out<<a.real;
if(a.imag < 0 && a.real != 0)
out<<"-j"<<-a.imag;
if(a.imag > 0 && a.real != 0)
out<<"+j"<<a.imag;
if(a.real == 0 && a.imag == 0)
out<<"0";
if(a.imag < 0 && a.real == 0)
out<<"-j"<<-a.imag;
if(a.imag > 0 && a.real == 0)
out<<"+j"<<a.imag;
return out;
}```

2. Code:
```#include <iostream>
using namespace std;

class Complex
{
public:
Complex(int a, int b)
{
real = a;
imag = b;
}

Complex()
{
}

~Complex()
{
cout<<"Complex destructor called."<<endl;
}

Complex operator +(const Complex &num) const;
friend ostream& operator<<(ostream& out, const Complex& obj);

private:
int real;
int imag;
};

Complex Complex::operator +(const Complex &num) const
{
Complex sum;
sum.real = real + num.real;
sum.imag = imag + num.imag;
return sum;
}

ostream& operator<<(ostream& out, const Complex& obj)
{
out<<obj.real<<" "<<obj.imag;
return out;
}

int main()
{
Complex a(1,1), b(2,-2);
cout<<a+b<<endl;

return 0;
}```
output:

Complex destructor called.
3 -1
Complex destructor called.
Complex destructor called.
Complex destructor called.

3. Here's my ouput from running SlyMaelstrom's code:

Copy constructor called.
Destructor called on object 3.
(16-20)
Destructor called on object 4.

VC++6 Rules!

4. In your matrix class, I believe you overloaded operator(), can I see it?

5. Ok so apparently the destructor IS called before. That is not my worry anymore I guess. But why is it not outputting to the screen with my Matrix class?

6. Sure. Here is the whole header file:

Code:
```//#include "Complex.h"

class Matrix
{
int row,col;
Complex **A;
bool empty, freq;
public:
Matrix();
Matrix(const Matrix&);
Matrix(const int&, const int&);
~Matrix();
Matrix operator*(const Matrix&) const;
Complex& operator()(const int&, const int&) const; //(1)
Matrix operator=(const Matrix&);
operator bool() const;
void LU(const Matrix&, Matrix&);
void SetFreqMode(const bool&);
friend ostream& operator <<(ostream&, Matrix const&);
};

Matrix::Matrix()
{
row = col = 0;
empty = true;
freq = true;
}

Matrix::Matrix(const Matrix &another)
{
A = new Complex* [another.row];
for (int i=0; i<row; i++)
A[i] = new Complex[another.col];

for (i=0; i<row; i++)
{
for (int j=0; j<col; j++)
{
A[i][j] = another(i,j);
}
}
}

Matrix::Matrix(const int &a, const int &b)
{
row = a;
col = b;

empty = false;

A = new Complex* [row];
for (int i=0; i<row; i++)
A[i] = new Complex[col];

for (i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
A[i][j] = 0;		//zero-out the entire matrix;
}
}
}

Matrix::~Matrix()
{
cout<<"Destroying matrix."<<endl;
if(!empty)
{
for (int i=0; i<row; i++)
delete[] A[i];
delete[] A;
}
}

Complex& Matrix::operator() (const int &a, const int &b) const // (2)
{
if(a<=row && b<=col)
return A[a][b];
else
{
cout<<"Error in Indexing. Aborting."<<endl;
return A[0][0];				//just for the sake of returning
}
}

Matrix Matrix::operator=(const Matrix &another)
{
//clearing heap
if(!empty)
{
for (int i=0; i<row; i++)
delete[] A[i];
delete[] A;
}

row = another.row;
col = another.col;

for (int i=0; i<row; i++)
{
for (int j=0; j<col; j++)
{
A[i][j] = another(i,j);
}
}
return *this;
}

Matrix Matrix::operator*(const Matrix &another) const //'const' keyword after => doesn't
{														//modify data members
if (col != another.row)
{
cout<<"Error in matrix multiplication. Matrix dimensions do not agree."<<endl;
return *this;
}

Matrix prod(row,another.col);
Complex sum(0,0);

for(int i=0; i<row; i++)		//i: 0 to 3
{
sum = 0;
for(int j=0; j<another.col; j++)	//j: 0 to 2
{
for(int k=0; k<row; k++)
{
sum = sum + A[i][k] * another(k,j);
}
//cout<<"prod("<<i<<","<<j<<") = "<<sum<<endl;
prod(i,j) = sum;
}
}
return prod;
}

void Matrix::SetFreqMode(const bool &flag)
{
freq = flag;
}

Matrix::operator bool() const
{
return freq;
}

void Matrix::LU(const Matrix &B, Matrix &X)
{
// forward substitution
Complex sum = 0;
int size = row;
for(int i=2; i<size; i++)
{
sum = B(i,0);
for(int j=1; j<=i-1; j++)
sum = sum - A[i][j]*B(j,0);
B(i,0) = sum;
}

//backward substitution
X(size-1,0) = B(size-1,0)/A[size-1][size-1];

for(int m=size-2; m>=0; m--)
{
sum=0;
for(int n=m+1;n<size;n++)
sum = sum + A[m][n]*X(n,0);
X(m,0) = (B(m,0) - sum)/A[m][m];
}
return;
}

/*
Notes:
(1)'const' after the function header means that the function does not modify data
contents; equivalently, it means that you can call the function on const objects
(2)'const' since it does not modify data members; although you can SET, which
changes data members, this change occurs in the actual line of code where it is
used, NOT in this funcion. This function only returns A[a][b].
*/```

7. Thanks all. My head is going to explode. I actually didn't expect you to stay that long on the topic. Anyway, I think I'll call it a night. Tomorrow's another day.

8. Code:
```Matrix Matrix::operator=(const Matrix &another)
{
//clearing heap
if(!empty)
{
for (int i=0; i<row; i++)
delete[] A[i];
delete[] A;
}

row = another.row;
col = another.col;

for (int i=0; i<row; i++)
{
for (int j=0; j<col; j++)
{
A[i][j] = another(i,j);
}
}
return *this;```
This is definitely dubious... You are deleting A[] and A and then you turn around and use A just a few lines later without re-newing them. Though really, if the memory is already allocated, I wouldn't delete and re-new I would just clear out the old values and assign the new. Maybe this is what you had intended.

9. You're definately right. Here is the corrected version:

Code:
```Matrix Matrix::operator=(const Matrix &another)
{
//clearing heap
if(!empty)
{
for (int i=0; i<row; i++)
delete[] A[i];
delete[] A;
}

row = another.row;
col = another.col;

//re-distributing matrix
A = new Complex*[row];
for (int i=0; i<row; i++)
A[i] = new Complex[col];

for (i=0; i<row; i++)
{
for (int j=0; j<col; j++)
{
A[i][j] = another(i,j);
}
}
return *this;
}```
I did this because let's say you have a 3x3 matrix A and then you assign A = B, where B is a 3x2 matrix. I would want to clear the whole matrix A and resize it to be 3x2.

10. After chaning the overloaded assignment operator, I tried to redo everything as before (i.e. passing by const reference, etc.), but it is still not outputting. ARRRRRGH!!!!

11. It might be better for Matrix::operator= to return a Matrix&

12. 1) Did you run both my examples?
2) Was the output the same as mine?
3) What compiler are you using?

13. Sorry if I didn't mention this before, but yes I did run both your examples and I did get the same output. I am using Microsoft Visuall C++ 6.0.

14. Turns out it is not printing at all. I tried using both the assignment operator and the copy constructor, but nothing works. It basically is never outputting to the screen. I am doing

Code:
```Matrix C;
C = A*B;
cout<<C<<endl;  //no output```
and

Code:
```Matrix C = A*B;
cout<<C<<endl;  //no output```
`cout<<A*B<<endl;  //no output`