Operating overloading allows you to pass different variable types to the same function and produce different results. In this article Ben gives us the low-down on operator overloading in C++.

Operator Overloading in C++ - Overloading (Page 4 of 7 )

Let's do some more interesting things with these matrices now. There are a number of mathematical operations that can be performed on a matrix, the simplest perhaps is addition. Addition of matrices requires that they both have the same dimensions. The resulting matrix is made by simply adding each number in the same position in each matrix and putting the answer in the same position as the two operands.

[1 0] [4 3] [5 3] [2 1] + [-1 0] = [1 1]

Since addition creates a new matrix, we don't want to return a reference, but an actual matrix object. Here's what the code looks like:

const Matrix operator+( const Matrix& m) { assert(numCols==m.numCols && numRows==m.numRows); Matrix theMatrix(numRows,numCols); for (int r=0;r<numRows;r++) for (int c=0;c<numCols;c++) theMatrix[r][c]=matrix[r][c]+m.matrix[r][c]; return theMatrix; }

This adds the current matrix to the matrix in argument m. We first assure that the dimensions are equivalent, then create a new matrix with the same dimensions as the sources. It is then a simple matter of adding the two sources, and returning the new matrix. Notice that we perform the actual math on the types that make up each row.

Matrix<float> a(2,2); Matrix<float> b(2,2);

Matrix<float> c(2,3);

Matrix<float> d=a+b;

Matrix<float> e=a+c;//will fail assertion, abort program

It is just as easy to define subtraction:

const Matrix operator-( const Matrix& m) { assert(numCols==m.numCols && numRows==m.numRows); Matrix theMatrix(numRows,numCols); for (int r=0;r<numRows;r++) for (int c=0;c<numCols;c++) theMatrix[r][c]=matrix[r][c]-m.matrix[r][c]; return theMatrix; }

Overloading += and -= += and -= are operators that both add and change the current object, so the code to describe it is a combination of +/- and =. We'll return a reference again because we don't want to create a new object, but just modify the existing one, which called the function. We'll just add whatever is currently in it to the other matrix, and return a reference to itself:

Matrix& operator+=(const Matrix& m) { assert(numCols==m.numCols && numRows==m.numRows); for (int r=0;r<numRows;r++) for (int c=0;c<numCols;c++) matrix[r][c]+=m.matrix[r][c]; return *this; }

Matrix& operator-=( const Matrix& m) { assert(numCols==m.numCols && numRows==m.numRows); for (int r=0;r<numRows;r++) for (int c=0;c<numCols;c++) matrix[r][c]-=m.matrix[r][c]; return *this; }

We can now expand our repertoire to include the following possibilities:

Matrix<int> a(2,1); Matrix<int> b(2,1);

a+=b; a-=b;

Scaling: Overloading * Another useful operation we can perform on matrices is scaling. This just multiples every element in the matrix by a constant.

[1 2] [2 4] [2 4] * 2 = [4 8]

This operation returns a new matrix so we will return by value, not reference. The code should be trivial to read by now:

const Matrix operator*(const float s) { Matrix theMatrix(numRows,numCols); for (int r=0;r<numRows;r++) for (int c=0;c<numCols;c++) theMatrix[r][c]=matrix[r][c]*s; return theMatrix; }

We use a float as the scalar, and multiply it by every value in the source matrix, and return a new matrix. It is left up to the reader to implement *=. (/ and /= could also be implemented as inverses of scaling, but since scaling allows a float, this is mostly redundant.)