I was creating a matrix class with overloaded operators in C++, I overloaded operators, << (output, with the ostream library), operator + that adds to matrices, operator = that's is used to assign one matrix to another. The problem is that when I use
cout<<m1+m2<<endl;
I get an error
E0349: No operator << matches these operands type are: std::ostream << Matrix
But if i do the following:
Matrix m = m1 + m2;
cout<<m<<endl;
it works perfect.
Here is the << operator:
ostream& operator<< (ostream &os,const Matrix& m)
{
if (m.isValid())
{
os << '|';
for (int i = 0; i < m.getRows(); i++)
{
for (int j = 0; j < m.getCols(); j++)
{
os << m.getMatrix()[i][j];
if (j < m.getCols() - 1)
{
os << ',';
}
}
os << '|';
}
}
else
{
os << "invalid matrix!";
}
return os;
}
The + operator:
Matrix Matrix::operator+ (Matrix &m)
{
Matrix* answer = new Matrix(m); //allocating space
if (valid && m.valid)//if they are both valid
{
if (colNum == m.colNum&&rowNum == m.rowNum) //if are from same size
{
answer->valid = true; //valid set to be true
for (int i = 0; i < rowNum; i++) //going over the matrix
{
for (int j = 0; j < colNum; j++)
{
answer->matrix[i][j] += matrix[i][j]; //adding data
}
}
}
else
{
//clearing data
delete answer;
answer = new Matrix();
}
}
else
{
//clearing data
delete answer;
answer = new Matrix();
}
return *answer;
}
And the = operator:
Matrix Matrix::operator= (Matrix &m)
{
int rows = m.rowNum; //putting cols and rows from the data
int cols = m.colNum;
if (m.valid)
{
matrix = new int*[rows]; //defining the matrix - first allocatin space for rows
for (int i = 0; i < rows; i++) //now allocating space for cols
{
matrix[i] = new int[cols];
}
for (int i = 0; i < rows; i++) //now going over the matrix and putting the data in
{
for (int j = 0; j < cols; j++)
{
matrix[i][j] = m.matrix[i][j];
}
}
}
//putting the rows and cols data
rowNum = m.rowNum;
colNum = m.colNum;
valid = m.valid; //setting to the right valid type
return *this;
}
and the class variables:
class Matrix
{
private:
bool valid;
int** matrix;
int rowNum;
int colNum;
There is a copy constructor a string constructor and a constructor that gets string input according to an algorithm and transforms it to a matrix.
You are actually faced with the fact that you Can't pass temporary object as reference (the link is to another question here on StackOverflow).
The solution in your case should be to replace:
ostream& operator<< (ostream &os,Matrix& m)
with:
ostream& operator<< (ostream &os,const Matrix& m)
as the overloaded operator signature. You currently expects an lvalue reference, In the case of
Matrix m = m1 + m2;
cout << m << endl;
that is what you're calling the function with m - a named variable and will outlive the execution of the command. In the failing case, you're calling the function with m1+m2 - the result of a plus operation, which is a temporary object. It just doesn't match your overload.
By the way - this change also makes sense because you're not modifying the matrix as you print it - you treat it as const.
Related
I have a class Matrix, and I'm trying to implement the method operator*=, which i use to make the product of two instances(matrix): m1*=m2.
I tried both method with friend and two parameter, and without friend and 1 parameter, but in both cases the results it's bad. Only with one parameter and the this use gives me results similar to the right (not always).
Tried with friend and 2 parameter, and without friend and 1 parameter. Tried returning directly the first matrix, m1, also creating a temporary matrix m3
My private members:
int N, M;
T** data;
bool Init(const int N_, const int M_);
void Clear();
(i'm using init to initialize the matrix/bidimensional array):
bool Matrix::Init(const int N_, const int M_) {
this->Clear(); //dealloco comunque prima di inizializzarla
N = N_;
M = M_;
if (N <= 0 || M <= 0) {
cerr << "Non posso generare una matrixe: " << N <<"x"<< M << endl;
return false;
}
else if (N > 0 && M > 0) {
data = new T*[N];
for (int i = 0; i < N; i++) {
data[i] = new T[M];
}
}
return true;
}
My operator *= mathod (no friend, 1 parameter):
Matrix& Matrix::operator*=(const Matrix& m2) {
float operation = 0;
int N_ = (this->N < m2.N) ? this->N : m2.N;
int M_ = (this->M < m2.M) ? this->M : m2.M;
Matrix m3(N_, M_);
if (this->N != m2.M || this->M != m2.N) {
this->Set(0, 0, flag_stop);
}
else {
for (int i = 0; i < this->N; ++i) {
for (int j = 0; j < m2.M; ++j) {
for (int k = 0; k < this->M; ++k) {
operation = operation + (this->Get(i,k) * m2.Get(k,j)) ;
//cout << " Cout m1 su "<< i<< ","<<k<<":"<< this->Get(i,k) << "\t " << " Cout m2: "<< m2.Get(k,j) << endl;
this->Set(i, j, operation);
}
//cout << operation << "\t";
operation = 0;
}
operation = 0;
}
}
return *this;
}
In the main, when i try to use the operator*=:
Matrix m1(i1,j1);
Matrix m2(i2,j2);
//operator*=
cout << endl;
m1*=m2;
int N_ = (m1.GetN() < m2.GetN()) ? m1.GetN() : m2.GetN();
int M_ = (m1.GetM() < m2.GetM()) ? m1.GetM() : m2.GetM();
for (int i = 0; i < N_; ++i) {
for (int j = 0; j < M_; ++j) {
cout << m1.Get(i,j) << "\t";
}
cout << endl;
}
It's all the day that i try, but the results are not rights
i also tried with m1[2][2] and m2[2][2], with m1[3][2] and m2[2][3], etc... but nothing. Someone have had a similar problem?
Hoping to have right product of two matrixes, but i have, at the major times, big numbers (expected 5, obtained 30), or the first column right numbers, and the second not
The reason for mistakes you report seems to be the multiplication algorithm itself. Basically, your multiplication code is as follows:
for (int i = 0; i < this->N; ++i) {
for (int j = 0; j < m2.M; ++j) {
for (int k = 0; k < this->M; ++k) {
operation = operation + (this->Get(i,k) * m2.Get(k,j)) ;
this->Set(i, j, operation);
}
operation = 0;
}
}
Your algorithm modifies the original matrix just in the process of the calculation (this->Set() call) so when you call this->Get(i,k) for any i < j you obtain not an original value of the first matrix at ith row and kth column but a value that was already modified by this->Set() call. This apparently leads to wrong results.
In order to solve this you must ensure that you use original matrix values for your calculations, for example, by making a copy of the original matrix or (more optimal) of the currently modified row of the original matrix.
The spec says that the function must return the row of the matrix specified by the "row number" in []
Class Definition:
class Matrix
{
public:
//functions taken out
private:
double ** matrix; // the matrix array
unsigned rows; // # rows
unsigned cols; // # columns
};
The brief main:
cout << "Test []: " << endl;
try {
Matrix row = m0[0]; //**m0 is Matrix m0(1,1); where the constructor creates the appropriate array**
cout << row << endl;
row = m0[1];
cout << row << endl;
row = m0[100]; // should throw an exception
} catch (const char * err) {
cout << err << endl;
}
The Function implementation:
double& Matrix::operator [](const unsigned int &sub)
{
if( sub >= rows)
{
const char * error = "Error: invalid row index";
throw error;
} else
{
return *matrix[sub];
}
}
Overloaded << operator for display:
//This is working for my other displays so this shouldn't be the problem
ostream &operator << (ostream &ostrm, const Matrix &obj)
{
//Loop through to display
for(unsigned int i = 0; i < obj.rows; i++)
{
for(unsigned int j = 0; j< obj.cols; j++)
{
ostrm << setw(10) << setprecision(3) << obj.matrix[i][j];
}
ostrm << endl;
}
return ostrm;
}
Overloaded = operator:
//Again this works for everything else
Matrix& Matrix::operator=(const Matrix &rhs)
{
//Copy Rows and Cols
rows = rhs.rows;
cols = rhs.cols;
//If statement to check for self assignment
if(&rhs == this)
{
return *this;
}
else
{
delete [] matrix;
matrix = new double*[rows]; //Allocate Dynamic Array
//Deep copy elements by looping and copying each element
for(unsigned int i = 0; i < rows; i++)
{
matrix[i] = new double[cols];
for(unsigned int j = 0; j < cols; j++)
{
matrix[i][j] = rhs.matrix[i][j];
}
}
return *this;
}
}
My Output:
Test []:
Error: invalid row index
Expected Output:
Test []:
17.2 -3 -0.5 6
8.2 4 3 1
Error: invalid row index
I am uncertain as to why the rows are not displaying or possibly not even being stored.
Thanks in advance
Aside comment: your assignment operator is leaking memory: you delete matrix, but you need to delete also the individual rows (using the original value of rows)
for(unsigned int i = 0; i < rows; i++)
delete[] matrix[i];
Your operator[] should return a double[] or double *, not a double - you want to return a whole row, not a single value.
Your "test []" code should not even compile... Matrix row = m0[0]; assigns a double to a Matrix object.
Etc.
Bottom line: just use Eigen.
The first line is wrong.
operator[] is returning a double. You assign it to a Matrix. The Matrix is initialized with one value. You've taken out your Constructors. Which one is called? I assume, the called constructor initializes the rows and cols members with zero. When they're zero, the output stream operator does nothing.
I managed to find a solution that worked for my question. Below is what I implemented in case someone else has a similar problem.
Matrix temp(1, cols); //Calls my constructor here
for(unsigned int i = 0; i < 1; i++)
{
for(unsigned int j = 0; j < cols; j++)
{
temp.matrix[i][j] = matrix[sub][j]; //Accessed temp's matrix and assigned it with what is in the matrix that called the function
}
}
return temp;
Thank you to everyone who helped and added some input. Much appreciated
I overwrote a + operator:
Matrix& Matrix::operator+(Matrix m1)
{
//This should never be triggered
if(this->data.capacity() != m1.data.capacity() || this->data[0].capacity() != m1.data[0].capacity())
{
cout << "Dimensions don't match, can't add.\n";
throw 7;
}
vector<vector<double>> result;
result.resize(m1.data.capacity());
for(int i = 0; i < m1.data.size(); i++)
{
result[i].resize(m1.data[0].size());
for(int j = 0; j < m1.data[0].size(); j++)
{
result[i][j] = m1.data[i][j] + this->data[i][j];
}
}
return Matrix(m1.getRows(),m1.getCols(), result);
}
This is the corresponding Constructor:
Matrix::Matrix(int rows, int cols, vector<vector<double>> data)
{
this->rows = rows;
this->cols = cols;
this->data = data;
}
Here's the executing code:
c = (a+b);
When I assign a breakpoint at the last line of the operator overload, I can see the correct results in result and both cols and rows are assigned correctly. When I step out, c has "rows" and "cols" set correctly, but data is empty. Why is that?
Your operator + is wrong. It should be returning a new object, not a reference to a local object (which is UB anyway).
I have a class project that is to make and operate on dynamic objects.
I have a class called Matrix that uses a 2 dimensional pointer array to store object of type Complex (which is a complex number class). I need to be able to add 2 arrays by adding all of the values in the arrays together and returning a new array. The issue is that I don't understand the syntax for accessing each Complex object in the array. Here is what I have so far for the overloaded addition operator:
const Matrix Matrix::operator+(const Matrix& rhs) const
{
Matrix newMatrix(mRows,mCols);
for(int i=0;i<mRows;i++)
{
for(int j=0;j<mCols;j++)
{
(*newMatrix.complexArray[i]) = (*complexArray[i])+ (*rhs.complexArray[i]);
}
}
return newMatrix;
}
Here is the overloaded input operator for the Matrix object:
istream& operator>>(istream& input, Matrix& matrix)
{
bool inputCheck = false;
int cols;
while(inputCheck == false)
{
cout << "Input Matrix: Enter # rows and # columns:" << endl;
input >> matrix.mRows >> cols;
matrix.mCols = cols/2;
//checking for invalid input
if(matrix.mRows <= 0 || cols <= 0)
{
cout << "Input was invalid. Try using integers." << endl;
inputCheck = false;
}
else
{
inputCheck = true;
}
input.clear();
input.ignore(80, '\n');
}
if(inputCheck = true)
{
cout << "Input the matrix:" << endl;
for(int i=0;i< (matrix.mRows+matrix.mCols);i++)
{
Complex* newComplex = new Complex();
input >> *newComplex;
matrix.complexArray[i] = newComplex;
}
}
return input;
}
Here is the Matrix class definition:
class Matrix
{
friend istream& operator>>(istream&, Matrix&);
friend ostream& operator<<(ostream&, const Matrix&);
private:
int mRows;
int mCols;
static const int MAX_ROWS = 10;
static const int MAX_COLUMNS = 15;
Complex **complexArray;
public:
Matrix(int=0,int=0);
Matrix(Complex&);
~Matrix();
Matrix(Matrix&);
Matrix& operator=(const Matrix&);
const Matrix operator+(const Matrix&) const;
};
And the constructor:
Matrix::Matrix(int r, int c)
{
if(r>0 && c>0)
{
mRows = r;
mCols = c;
}
else
{
mRows = 0;
mCols = 0;
}
if(mRows < MAX_ROWS && mCols < MAX_COLUMNS)
{
//complexArray= new Complex[mRows];
complexArray= new Complex*[mRows];
for(int i=0;i<mRows;i++)
{
complexArray[i] = new Complex[mCols];
}
}
}
As it is now, the program compiles, but stops working when it gets to the addition of matrices during runtime. If anyone can tell me what syntax I should be using and why, it would be extremely helpful.
You don't seem to be taking in enough input. You're taking (rows+cols) complex numbers as input but then attempting (correctly) to iterate over (rows*cols) elements within the matrix.
for(int i=0;i< (matrix.mRows+matrix.mCols);i++)
versus
for(int i=0;i<mRows;i++)
{
for(int j=0;j<mCols;j++)
I am trying to learn operator overloading by working on overloading >> for a matrix class to enable the key-board based input for a matrix by calling sth such as
Matrix M1;
cin >> M1;
The operator overloading part is given in the following
istream &operator>>(istream &in, Matrix &m)
{
for (int i = 0; i < m.dx; ++i) {
for (int j = 0; j < m.dy; ++j)
in >> m.p[i][j];
}
return in;
}
It turns work that my implementation was not correct at all. Can you let me know why this implementation is wrong?
I implemented the above part by imitating an existing implementation of overloading >>, which has been proven to work fine in the matrix output part, like cout<< A; where A is a matrix
ostream &operator<<(ostream &out, const Matrix &m)
{
for (int i = 0; i < m.dx; ++i) {
for (int j = 0; j < m.dy; ++j)
out << m.p[i][j] << " ";
out << endl;
}
return out;
}
I believe that the problem with your operator >> is that you're using whatever dimensions already happen to be in the Matrix rather than trying to recover the dimensions from the input that you find.
I think that your best bet would be to have the operator << implementation preface the matrix with dimension information (such as the number of rows and columns) and then have the operator >> function read in that information. For example:
ostream &operator<<(ostream &out, const Matrix &m)
{
out << m.dx << ' ' << out.dy << '\n';
for (int i = 0; i < m.dx; ++i) {
for (int j = 0; j < m.dy; ++j)
out << m.p[i][j] << " ";
out << endl;
}
return out;
}
With this in hand, you can write your stream extraction operator as
istream &operator>>(istream &in, Matrix &m)
{
in >> m.dx >> m.dy;
/* Some sort of logic to ensure that you've allocated an array large enough to
* hold all the elements ...
*/
for (int i = 0; i < m.dx; ++i) {
for (int j = 0; j < m.dy; ++j)
in >> m.p[i][j];
}
return in;
}
This may not be the most aesthetically pleasing input and output operators, but they should get the job done.
If you want to make these operators a bit classier, consider outputting the elements of the matrix using some special character to delimit rows and columns. For example, you might try outputting the matrix
0 1 2
3 4 5
6 7 8
as
[[0 1 2][3 4 5][6 7 8]]
With this setup, the size information about the matrix is implicit in how the bracket grouping works. Then again, this may make it a bit trickier to read the input, since you wouldn't know in advance how large the matrix is. But go with what's easiest for yourself overall.
As an FYI, you probably don't want to use endl to delimit lines when writing a stream insertion operator. In addition to writing a newline, endl flushes the buffer. If your stream is hooked up to a network connection, you may not want to keep flushing the buffer whenever you have a new line of the matrix, since that could result in a lot of data getting sent in bursts (slow) rather than grouping it all together at once (fast).
Hope this helps!
I don't think your code is wrong particularly.
If pressed I would suggest checking the stream condition in the loop.
For your information, the following code worked when I tested:
struct Matrix {
static int const dx = 2, dy = 2;
int p[ dx ][ dy ];
};
istream &operator>>(istream &in, Matrix &m)
{
for (int i = 0; i < m.dx; ++i) {
for (int j = 0; j < m.dy; ++j)
if ( ! (in >> m.p[i][j]) ) return in;
}
return in;
}
int main() {
Matrix M1;
cin >> M1;
cout << M1;
}
Hope this helps
#include<iostream>
using namespace std;
class Array /*overload of subscript operator of 1D array*/
{
private: int *p;
public:
int length;
Array(int size = 0): length(size)
{
p=new int(length);
}
int& operator [](const int k)
{
return p[k];
}
};
class Matrix
{
private: Array *p;
public:
int r,c;
Matrix(int i=0, int j=0):r(i), c(j)
{
p= new Array[r];
}
Array& operator [](const int& i)
{
return p[i];
}
friend istream& operator >> (istream& in, Matrix& m);
/*friend ostream& operator << (ostream& out, Matrix& m);*/
};
istream& operator >> (istream& in, Matrix& m)
{
for(int i=0 ; i < m.r ; i++)
{
for(int j=0 ; j < m.c ; j++)
in >> m[i][j];
}
}
/*ostream& operator << (ostream& out, Matrix& m)
{
for(int i=0 ; i < m.r ; i++)
{
for(int j=0 ; j < m.c ; j++)
out << m[i][j] << " ";
out << endl;
}
}*/
/*Driver program*/
int main()
{
Matrix M1(3,3); /*for checking purpose*/
cin >> M1;
/*cout << "\n" << M1;*/
}