Comp 2673
Spring 2002
Homework 3 solutions
  1. cat, head, tail, more
  2. Here are the contents of matrix.h:
    #ifndef MATRIX_H
    #define MATRIX_H
    
    class Matrix {
        friend ostream&operator<<(ostream &, const Matrix &);
        friend istream&operator>>(istream &, Matrix &);
    public:
       Matrix():numrows(0), numcols(0), contents(0){};
       Matrix(const Matrix &);  // copy constructor
       ~Matrix();
       const Matrix &operator=(const Matrix &);
       bool operator==(const Matrix &) const;
       const Matrix operator+(const Matrix &) const;
       const Matrix &operator+=(const Matrix &); 
       bool same_dim(const Matrix &) const;
       // many other arithmetic operators should be added to the class
    private:
       int numrows;
       int numcols;
       float *contents;
    };
    #endif
    
    Here are the 6 functions that were to be implemented:
    // Copy constructor
    Matrix::Matrix(const Matrix &m)
    :numrows(m.numrows), numcols(m.numcols), contents(0)
    {
        // Allocate space, then copy the contents
        int i;
        if (numrows*numcols) {
            contents = new float[numrows*numcols];
            assert(contents); // quit gracefully if allocation failed
            for (i=0; i < numrows*numcols; i++)
                contents[i] = m.contents[i]; 
        }
    }
    
    Matrix::~Matrix()
    {
        // release space, reset variable values
        if (contents) delete [] contents;
        numrows=numcols=0;
        contents=0;
    }
    
    const Matrix& Matrix::operator=(const Matrix &rhs)
    {
        int i;
        if (&rhs != this) {  // don't copy from self to self
            // change size of storage space if necessary:
            if (numrows*numcols != rhs.numrows*rhs.numcols) { 
                if (contents) delete [] contents;
                if (rhs.numrows*rhs.numcols) {
                    contents = new float[rhs.numrows*rhs.numcols];
                    assert(contents); // quit gracefully if allocation failed
                }
                else contents=0;
            } 
            // copy the contents
            numrows=rhs.numrows;
            numcols=rhs.numcols;
            for (i=0; i < numrows*numcols; i++)
                contents[i] = rhs.contents[i];
        }
        return *this;
    }
    
    bool Matrix::operator==(const Matrix &rhs) const
    {
        // check if the size is the same, and if so, check that contents are same
        int i;
        if (numrows != rhs.numrows || numcols != rhs.numcols) return false;
        for (i=0; i < numrows*numcols; i++)
            if (contents[i] != rhs.contents[i]) return false;
        return true;
    }
    
    const Matrix Matrix::operator+(const Matrix &rhs) const
    {
        int i;
        Matrix ans;
        // you can only add if the dimensions match
        if (numrows!=rhs.numrows || numcols!=rhs.numcols) return ans;  
        // make space to store the answer:
        if (numrows*numcols) {
            ans.contents = new float[numrows*numcols];
            assert(contents); // quit gracefully if allocation failed
        }
        // add the two matrices (componentwise)
        for (i=0; i < numrows*numcols; i++)
            // matrix addition means add elements componentwise
            ans.contents[i] = contents[i]+rhs.contents[i];
        return ans;
    }
    
    const Matrix &Matrix::operator+=(const Matrix &rhs)
    {
        int i;
        // you can't add if the dimensions don't match:
        if (rhs.numrows !=numrows || rhs.numcols !=numcols) return *this;
        // add the contents of right-hand-side (compontwise) to *this
        for (i=0; i < numrows*numcols; i++)
            contents[i] += rhs.contents[i];
        return *this;
    }
    
  3. Design will vary greatly from person to person.