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