Assignment 6: Operator Overloading, Friends, & Const (20 points)

This assignment introduces the concept of operator overloading, the use of the friend keyword, and the concept of "const correctness".

In mathematics, a matrix (plural matrices) is a rectangular array of numbers, symbols, or expressions, arranged in rows and columns. The dimensions of the matrix below are 2 x 2 (read "two by two"), because there are two rows and two columns.

    2x2 matrix

The individual items in a matrix are called its elements or entries. Provided that they are the same size (have the same number of rows and columns), two matrices can be added or subtracted element by element. The rule for matrix multiplication, however, is that two matrices can be multiplied only when the number of columns in the first equals the number of rows in the second. Any matrix can be multiplied element-wise by a scalar from its associated field.

If the matrix is square (has the same number of rows as columns), it is possible to deduce some of its properties by computing its determinant. For example, a square matrix has an inverse if and only if its determinant is not zero.

Note that in mathematics, the rows and columns of a matrix are numbered starting from 1, not 0 like a C++ array.

Files We Give You

A suitable Makefile, main.cpp and a copy of the output shown below is available on hopper in this directory:

/home/hopper/winans/501/a6/

You must not modify the files we give you. When we grade your assignment, we will ignore any Makefile and main.cpp file that you submit and will use our own.

Files You Must Write

You will need to write one class for this assignment. A main program to test your class will be provided.

The matrix class

The matrix class represents a two by two square matrix using a two-dimensional array of integers. This class must be implemented as two separate files.

The class definition must be placed in a header file called matrix.h. Include header guards to make it impossible to accidentally #include it more than once in the same source code file.

The matrix class must contain the following private data member:

In addition to the data member described above, the class definition must also contain prototypes for the member functions described below.

The implementations of the class member functions must be placed in a separate source code file called matrix.cpp. Make sure to #include "matrix.h" at the top of this file.

The matrix class must have the following member functions:

Note: Member functions that do not alter the data members of the object that called them must be declared to be const. That will allow them to called using const objects.

In addition to the member functions described above, you will need to write two standalone functions. These functions are not (and can not be) member functions. You should

  1. Include a friend declaration for each of these functions in the matrix class declaration.
  2. Put the definitions for these functions in matrix.cpp.

Output

The correct output for this assignment is shown below:

1. Testing identity matrix constructor

m1 = [[1, 0], [0, 1]]

2. Testing array initialization constructor

m2 = [[5, 7], [3, 2]]
m3 = [[2, 3], [1, 4]]

3. Testing determinant

det[[5, 7], [3, 2]] = -11
det[[2, 3], [1, 4]] = 5

4. Testing matrix addition

[[5, 7], [3, 2]] + [[2, 3], [1, 4]] = [[7, 10], [4, 6]]
[[2, 3], [1, 4]] + [[5, 7], [3, 2]] = [[7, 10], [4, 6]]

5. Testing scalar multiplication

[[5, 7], [3, 2]] * 2 = [[10, 14], [6, 4]]
4 * [[5, 7], [3, 2]] = [[20, 28], [12, 8]]
[[2, 3], [1, 4]] * 2 = [[4, 6], [2, 8]]
4 * [[2, 3], [1, 4]] = [[8, 12], [4, 16]]

6. Testing matrix multiplication

[[5, 7], [3, 2]] * [[2, 3], [1, 4]] = [[17, 43], [8, 17]]
[[2, 3], [1, 4]] * [[5, 7], [3, 2]] = [[19, 20], [17, 15]]
[[2, 3], [1, 4]] * [[1, 0], [0, 1]] = [[2, 3], [1, 4]]
[[1, 0], [0, 1]] * [[2, 3], [1, 4]] = [[2, 3], [1, 4]]

det(m2 * m3) and det(m2) * det(m3) are equal

7. Testing relational operators

[[5, 7], [3, 2]] and [[5, 7], [3, 2]] are equal
[[5, 7], [3, 2]] and [[2, 3], [1, 4]] are not equal
[[2, 3], [1, 4]] and [[5, 7], [3, 2]] are not equal
[[1, 0], [0, 1]] and [[2, 3], [1, 4]] are not equal

If you would like a copy of this output to compare against your own program's output using the diff command, it is available on Unix at the pathname /home/hopper/winans/501/a6/output6.txt.

Hints


The driver program is designed to make this assignment easy to develop incrementally. Simply comment out all of the lines of the driver program that call functions that you haven't written yet. You should be able to write, test, and debug function at a time. I would suggest writing the functions in the following order:

  1. "Identity matrix" constructor
  2. operator<<() function
  3. "Array initialization" constructor
  4. determinant() method
  5. operator+() method (matrix addition)
  6. operator*() method (scalar multiplication with integer as right operand)
  7. operator*() function (scalar multiplication with integer as left operand)
  8. operator*() method (matrix multiplication)
  9. operator==() method
  10. operator!=() method

Remember that member functions that do not change any data members of the object that called them should be made const so that they may be called by const objects. If not, you will get the syntax error message "error: passing 'const matrix' as 'this' argument discards qualifiers" when the member function is called by a const object.