[comp.lang.c++] Efficient return of objects from overloaded operators

bjaspan@athena.mit.edu (Barr3y Jaspan) (04/17/91)

In my Matrix class, I have several overloaded operators of the form

Matrix operator*(const Matrix&, const Matrix&);

The function does the obvious thing: allocates a local Matrix on the stack,
multiplies into it, and returns it.  This, of course, is very inefficent
because I have to copy the Matrix object out of the stack frame at the end. 
Is there a good solution for this problem?  Unacceptable solutions I've
thought of:

(1) Have a static Matrix local to the function.  No good because it will fail
in the multithreaded environment.

(2) Allocate a matrix on the heap and return a reference to it.  No good
because then the matrix is never freed (since there is no garbage collection).

The only possibly good solution I've thought of (I haven't worked through it
to make sure it's a good idea) is allocate a matrix on the heap and return a
smart reference that will deallocate the object when it is no longer used.  In
fact, I have a copy-on-write template that would be ideal for this, since it
would provide COW semantics in addition to avoiding the copy of the stack
object.  But that would mean I'd have to implement an entire set of operators
like COW<Matrix>& operator*(const COW<Matrix>&, const COW<Matrix>&) etc., and
this seems kind of tedious.  (It also means the Matrix class would depend on a
specific smart reference class, which doesn't seem like a good idea.)

Suggestions?

-- 
Barr3y Jaspan, bjaspan@mit.edu

mittle@blinn.watson.ibm.com (Josh Mittleman) (04/19/91)

One approach is to have your Matrix class contain a pointer to an
auxilliary object MatrixData, which actually contains the matrix data.
This object is normally allocated, initialized, and/or copied in the
constructors and operator=, and deallocated in ~Matrix().  You need one
extra constructor, Matrix::Matrix(int cols, int rows, MatrixData&), which
should be private.

Then, to write a function which returns Matrix, by value, you allocate a
MatrixData on the heap, initialize its value within the function, and then
return a reference to it.

This avoids the need to copy the data.  Of course, it does introduce a
small amount of overhead in pointer chasing.

===========================================================================
Josh Mittleman (mittle@watson.ibm.com or joshua@paul.rutgers.edu)
J2-C28 T.J. Watson Research Center, PO Box 704, Yorktown Heights, NY  10598