If I have this main:

{
   Matrix m1(3,3), m2(3,6), m3;
   Matrix m4(2,3);
   m1 = m1 + m2;
   m1.print();
   m3 = m1 * m2;
   m3.print();
}

then how do I need to adjust this implementation file to work with it!?(Right now I'm just trying to get the '+' '=' to work, then I'll move on to the '*'):

Matrix & Matrix::operator = (Matrix &m)
{
	numCols = m.numCols;
	numRows = m.numRows;
	return m;
}



Matrix Matrix::operator+(Matrix & m)//m2
{
	m.numCols += numCols;
	m.numRows += numRows;
	return m;
}

Recommended Answers

All 12 Replies

>>then how do I need to adjust this implementation file to work with it!?
You have to add two more methods: (1) print(), and (2) the * operator. The code you posted already has the = and + operators so make the * operator look similar to that + operator. Just substitute * for + and you have it done.

Ok..I get it. I can't get my for loop to print what I want for the print func though.

How do I cout a matrix!!!!? I'm assuming I have to do it with a for loop...but HOW?!

I have no idea because I don't know what the matrix class looks like. You did not post it. But probably something like this:

for(int row = 0; row < numRows; ++row)
{
   for(int col = 0; col < numCols; ++col)
   {
        cout << data[row][col] << " ";
   }
   cout << "\n";
}

My bad, but I was able to adjust that to make it work with my code..thank you!

How do I multiply them though?

Actually I think my previous post was wrong. You can't multiply two matrices by simply using the + operator and replacing the + with a *. And I don't think the + operator you posted is correct (or complete) either.

>>How do I multiply them though?

How about something like this->data[i][j] *= m.data[i][j]; . Put that inside an i and j loop where i goes from 0 to numRows and j from 0 to numCols

Yea, I think I figured out the '+' function..


For the '*' loop, do I then just return data..?

Ok, scratch that...I'm having troubles using my 'data' pointer. How do I need to address it in my constructor so it will work properly??

Here's all my code, so you can see what's goin on better...:

main:

//***********Main************


#include <iostream>
using namespace std;

#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#include "Matrix.h"

void doit()
{
   Matrix m1(3,3), m2(3,3), m3;
   Matrix m4(2,3);
   m1 = m1 + m2;
   m1.print();
   m3 = m1 * m2;
   m3.print();
   // The following statements will throw exceptions.
   // Wrap them with try, catch to keep on running

   try
   {
        int x = m3.get(4,2);
   }
   catch (MatrixException e)
   {
       cout << "We expected this:(bad call to get) " 
            << e.getError() << endl;
   }
   try
   {
        m3 = m1 + m4;
   }
   catch (MatrixException e)
   {
       cout << "We expected this:(bad Matrix add) " 
            << e.getError() << endl;
   }

   try
   {
        m3 = m3 * m4;
   }
   catch (MatrixException e)
   {
       cout << "We expected this:(bad Matrix Multiply) " 
            << e.getError() << endl;
   }
   
   m1.put(3,1,0);
   m1.put(3,0,1);
   m1.print();
//   int det = m1.determinant();
//   cout << "Determinate = " << det << endl;
}

int main()
{
    doit();  
    _CrtDumpMemoryLeaks();
}

cpp:

#include <iostream>
using namespace std;

#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#include "Matrix.h"


MatrixException::MatrixException(const char * err)
{
	m_err = err;
}



MatrixException::MatrixException (const char *err, const char * filename, int lineNum)
{
	m_err = err;
}

const char * MatrixException::getError()
{
	return m_err.c_str();
}



Matrix::Matrix()
{
	numCols = 0;
	numRows = 0;
	data = NULL;
}


Matrix::Matrix(int r, int c)
{
	numCols = c;
	numRows = r;
}

Matrix::~Matrix()
{
}


Matrix::Matrix(Matrix &m)
{
	numCols = 0;
	numRows = 0;
}


Matrix & Matrix::operator = (Matrix &m)
{
	Matrix temp;
	temp.numCols = m.numCols;
	temp.numRows = m.numRows;
	return temp;
}



Matrix Matrix::operator+(Matrix & m)//m2
{
	Matrix temp;
	numCols += m.numCols;
	numRows += m.numRows;
	temp.numCols = numCols;
	temp.numRows = numRows;
	return temp;
}
Matrix Matrix::operator-(Matrix & m)
{
	Matrix m2;
	m2.numCols = numCols - m.numCols;
	m2.numRows = numRows - m.numRows;
	return m2;
}

Matrix Matrix::operator*(Matrix & m)
{
	for (int i=0; i<numRows; i++)
	{
		for (int j=0; j<numCols; i++)
			this->data[i][j] *= m.data[i][j]; //Put inside an i and j loop where i goes from 0 to numRows and j from 0 to numCols
	}
	return m;  //??
}

Matrix Matrix::operator*(int multiplier)
{
        //???
	numCols = multiplier;
	numRows = multiplier;
}




    // throw an exception in illegal situations
int& Matrix::operator [](int n)
{
        //???
	return n;
}


int& Matrix::get (int r, int c)
{
        //???
	numCols = c;
	numRows = r;
	return r;
}


int& Matrix::get (int n)  // n is computed as c + r*numCols
{
        //???
	return n;
}


void Matrix::put(int value, int r, int c)
{
        //???
	numCols = c;
	numRows = r;
}
   

void Matrix::print()
{
	for(int row = 0; row < numRows; ++row)
	{
	   for(int col = 0; col < numCols; ++col)
	   {
			cout << data[row][col] << " ";
	   }
	   cout << "\n";
	}
}

header:

//************Header*************


//Note that there are lots of error possibilities that should
//generate exceptions. 
#ifndef _MyException
#define _MyException

#define THROW(x) throw MatrixException(x, __FILE__, __LINE__)


class MatrixException
{
    string m_err;
public:
    MatrixException(const char * err);

// Note this can be invoked by something like:
// throw MatrixException("Some error msg", __FILE__, __LINE__);
// The compiler will automatically fill in __FILE__ with the name
// of the file you are in, and __LINE__ with the line number you 
// are at when you throw this exception.

    MatrixException (const char *err, 
        const char * filename, int lineNum);
    const char * getError();
};

class Matrix
{
    int numCols, numRows;
    int *data;
    void cloneMe(Matrix &m);
public:
    // If we use this constructor, data will be set to NULL. We must check this pointer on
    // all useages of this instance.
    Matrix(); 

// Assume this constructor prefills the matrix with 1's
   
    Matrix(int r, int c);
    ~Matrix();    
    // Why do we need this ....
    Matrix(Matrix &m);    
    Matrix & operator = (Matrix &m);

    // In the following operator definitions, what are the illegal cases 
    //      where we need to throw exceptions
    Matrix operator+(Matrix & m);
    Matrix operator-(Matrix & m);
    Matrix operator*(Matrix & m);    
    Matrix operator*(int multiplier);

    // If you are a math wizard, try this out
    // What error cases do we have for throwing exceptions
    //int determinant();

    // throw an exception in illegal situations
    int& operator [](int n); 
    int& get (int r, int c); 
    int &get (int n); // n is computed as c + r*numCols
    void put(int value, int r, int c);
   

    void print();
   
};

#endif

You class has several problems. I am not detailing all of them, but giving you a few to get you going.
1. data must be declared as a 2-dimensional array. What you have is only one dimensional. It can work that way but is somewhat more difficult. Should be declared like this with two stars, not one: int **data; 2. The constructor needs to allocate space for the matrix

Matrix::Matrix(int r, int c)
{
	numCols = c;
	numRows = r;
    data = int*[numRows];
    for(int i = 0; i < numRows; i++)
        data[i] = new int[numCols];
}

The destructor needs to delete the matrix

Matrix::~Matrix()
{
    if(data)
    {
        for(int i = 0;i < numRows; i++)
        {
            delete[] data[i];
            data[i] = 0;
        }
        delete[] data;
        data = 0;
    }
}

The copy constructor needs to delete the current matrix if it exists and copy the matrix from the parameter

Matrix::Matrix(Matrix &m)
{
    if(data)
    {
        for(int i = 0;i < numRows; i++)
        {
            delete[] data[i];
            data[i] = 0;
        }
        delete[] data;
        data = 0;
    }
    numCols = m.numCols;
    numRows =  m.numRows;
    data = int*[numRows];
    for(int i = 0; i < numRows; i++)
        data[i] = new int[numCols];

}

AS lovely as that sounds..I'm not allowed to change the header or main...so data has to stay as *data...Is that still possible?

I was just taking a looking at that too.
Like I said before you can use a 1d array to simulate a 2d matrix if you do the math.

void Matrix::delData()
{
    if(data)
    {
        delete[] data;
        data = 0;
    }

}
void Matrix::allocate()
{
    delData();
    int n = numCols * numRows;
    data = new int[n];
    for(int i = 0; i < n; i++)
        data[i] = 0;

}
Matrix & Matrix::operator = (Matrix &m)
{
    delData();
	numCols = m.numCols;
	numRows = m.numRows;
    allocate();
    int n = numCols * numRows;
    for(int i = 0; i < n; i++)
        data[i] = m.data[i];
     return *this;
}

Ok, I see.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.