Steve Jackson

Just as I was about to pat myself on the back for finally understaning pointers, I encountered this problems that reminded me once again of my ignorance.

So, consider the operator overload below.



Code Snippet

MatrixType MatrixType::operator +(MatrixType &rightMatrix)
{
MatrixType* _result;
int _cols = this->getCols();
int _rows = this->getRows();

if ((rightMatrix.getCols() != _cols) || (rightMatrix.getRows() != _rows))
{
throw ("Cannot add matrices of different sizes");
}

_result = new MatrixType(_cols, _rows);

// Code here that fills _result with elements
// I have verified that _result does indeed get
// correctly filled.


return *_result;

}


Now consider how I use it. When I call *_matrix3 = *_matrix1 + *_matrix2 (below),
the code compiles and runs OK but _matrix3 ends up with undefined elements.
Its size is OK, but the elemets are not what was returned from the operator
overload+ method. I've tried some variations on this, using *, not using *, but I
get compile errors. I'm at a loss of how to set this up. Any ideas

Code Snippet

void MatrixTester::BeginTest()
{

MatrixType* _matrix1;
MatrixType* _matrix2;
MatrixType* _matrix3;


// Some code here to fill _matrix1 and _matrix2

_matrix3 = new MatrixType(_matrix1->getCols(), _matrix1->getRows());
*_matrix3 = *_matrix2 + *_matrix1;

}

Thanks,




Re: Visual C++ General Returning dynamically created object;

Steve Jackson

Part of the puzzle solved. I remembered from reading, the need for copy
constructors - so I added one. It still does the same thing though. I verified, using
debugger that the copy constructor is being called - but in the end I still get an empty
result.


It might be helpful to know, when looking at the code below. What I call a matrix is really
an array of doubles, whose columns are stacked end to end to form an array of length
cols*rows. It was easier to implement that way.

Code Snippet

// *******************************************************************
// COPY CONSTRUCTOR
//
MatrixType::MatrixType(MatrixType &otherObject)
{
cols = otherObject.getCols();
rows = otherObject.getRows();

matrix = new double[rows*cols];

for (int c = 0; c < cols; c++)
{
for (int r=0; r < rows; r++)
{
this->setElement(c,r,otherObject.getElement(c,r));
}
}


}


Thanks,






Re: Visual C++ General Returning dynamically created object;

Steve Jackson

OK, I finally got it - for those of you who are interested. What I needed was not the copy constructor, but to overide the operator=.

For those that are interested, I've included the code below for the operator= overload.

Code Snippet

// *************************************************************
// OPERATOR OVERLOAD =
//
MatrixType MatrixType::operator =(MatrixType &rightObject)
{

cols = rightObject.getCols();
rows = rightObject.getRows();

matrix = new double[rows*cols];

for (int c = 0; c < cols; c++)
{
for (int r = 0; r < rows; r++)
{
this->setElement(c,r,rightObject.getElement(c,r));
}
}

return *this;
}

BTW: Is is considered good ediquite to mark oneself as answering ones own post






Re: Visual C++ General Returning dynamically created object;

Andreas Masur

Steve Jackson wrote:
OK, I finally got it - for those of you who are interested. What I needed was not the copy constructor, but to overide the operator=.

For those that are interested, I've included the code below for the operator= overload.



Glad you found the answer yourself...however, as a small enhancement to your assignment operator...you really want to check for self-assignment first thus:


Code Snippet

// *************************************************************
// OPERATOR OVERLOAD =
//
MatrixType MatrixType::operator =(MatrixType &rightObject)
{

if(&rightObject != this)

{

cols = rightObject.getCols();
rows = rightObject.getRows();

matrix = new double[rows*cols];

for (int c = 0; c < cols; c++)
{
for (int r = 0; r < rows; r++)
{
this->setElement(c,r,rightObject.getElement(c,r));
}
}

}

return *this;
}






Re: Visual C++ General Returning dynamically created object;

Steve Jackson


Thanks, Andreas;

I think I read this somewhere as well. From an efficiency perspective, I get why there is no value to duplicating ones self. Is there any other reason than for that of efficiency

Thanks,







Re: Visual C++ General Returning dynamically created object;

Andreas Masur

Steve Jackson wrote:
I think I read this somewhere as well. From an efficiency perspective, I get why there is no value to duplicating ones self. Is there any other reason than for that of efficiency


Steve,

Yes, there is another reason...dynamically allocated memory managed by your class. The sequence of the assigment operator is as follows:


  1. Release any dynamically allocated memory managed by this class
  2. Allocate memory to hold the contents of the class to be assigned
  3. Copy the contents of the class to be assigned
  4. Return this class


Now...by looking at the above sequence, it should become clear why checking for self-assigment is a *must*...

Okay....if it does not jump at you....the problem is with the first two steps...if you assign a class that contains dynamically allocated memory to itself, the memory (and its content) will be lost before they are copied over. In other words, after the self-assigment, your data is lost.






Re: Visual C++ General Returning dynamically created object;

Simple Samples

Steve Jackson wrote:
BTW: Is is considered good ediquite to mark oneself as answering ones own post

I think so for this thread up to here. It is good that you gave recognition to Andreas for subsequent help. Many people mark their posts as answers when I think it is not appropriate but it seems appropriate here.

One thing I think is relevant is to point out that this seems to be a VC language question so it should be in the other forum.