C++ increment operator overload as friend function not working? - c++

I'm just going to preface this with the fact that I'm new to C++ so it's quite possible there's just a stupid error here, but I can't find it.
I'm just trying to overload the increment operator in a friend function. Everything compiles perfectly and everything works if I explicitly call the postfix increment overload:
operator++(*test, 0);
Every element in the matrix is incremented and the program prints it out using cout perfectly. The problem is when I try to do the normal ++ increment test++; it appears as though something wrong happens with the test pointer to where when it tries to print the test object it doesn't print anything.
Any idea what's going on? I'm clueless. Here's the code I'm working with...
Compile & Run
g++ -o App App.cpp Matrix.cpp
./App
App.cpp
#include <iostream>
#include "Matrix.h"
using namespace std;
#define X 9
int main(int argc, char *argv[])
{
// Start the actual program here
Matrix* test = new Matrix(3,3);
// Row 1
test->setElement(0,0,1);
test->setElement(0,1,2);
test->setElement(0,2,3);
// Row 2
test->setElement(1,0,4);
test->setElement(1,1,5);
test->setElement(1,2,6);
// Row 3
test->setElement(2,0,7);
test->setElement(2,1,8);
test->setElement(2,2,9);
operator++(*test, 0);
//test++;
//++test;
// Print the Matrix object
cout << *test << endl;
}
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <iostream>
using namespace std;
class Matrix {
friend ostream& operator<<(ostream&, const Matrix&);
friend Matrix& operator++(Matrix&); // prefix increment
friend Matrix& operator++(Matrix&, int); // postfix increment
private:
int rows;
int cols;
int** elements;
public:
// Constructors
Matrix(int);
Matrix(int,int);
Matrix(const Matrix&);
// Define setters
void setElement(int,int,int);
// Define getters
int getRowCount();
int getColCount();
int getElementAt(int,int);
void increment();
// Destructor
~Matrix();
};
#endif
Matrix.cpp
#include <iostream>
#include "Matrix.h"
using namespace std;
//===================================
// DEFINE [CON]/[DE]STRUCTORS
//===================================
// Constructor for creating square matricies
Matrix::Matrix(int _size) {
rows = _size;
cols = _size;
elements = new int*[_size];
for (int i = 0; i < _size; i++) {
elements[i] = new int[_size];
}
}
// Constructor for supporting non-square matricies
Matrix::Matrix(int _rows, int _cols) {
rows = _rows;
cols = _cols;
elements = new int*[_rows];
for (int i = 0; i < _rows; i++) {
elements[i] = new int[_cols];
}
}
// Copy constructor
Matrix::Matrix(const Matrix& mat1) {
Matrix(mat1.rows, mat1.cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
elements[i][j] = mat1.elements[i][j];
}
}
}
// Destructor
Matrix::~Matrix() {
for (int i = 0; i < rows; i++) {
delete[] elements[i];
}
delete[] elements;
}
//===================================
// DEFINE SETTER FUNCTIONS
//===================================
void Matrix::setElement(int row, int col, int newElement) {
if (row > rows-1 || row < 0)
throw "Row out of index";
if (col > cols-1 || col < 0)
throw "Column out of index";
elements[row][col] = newElement;
}
//===================================
// DEFINE GETTER FUNCTIONS
//===================================
int Matrix::getRowCount() { return rows; }
int Matrix::getColCount() { return cols; }
int Matrix::getElementAt(int row, int col) {
if (row > rows-1 || row < 0)
throw "Row out of index";
if (col > cols-1 || col < 0)
throw "Column out of index";
return elements[row][col];
}
//===================================
// OVERRIDE OPERATOR FUNCTIONS
//===================================
// Print the Matrix to the output stream
ostream& operator<<(ostream& out, const Matrix& mat) {
for (int i = 0; i < mat.rows; i++) {
for (int j = 0; j < mat.cols; j++) {
out << mat.elements[i][j] << " ";
}
out << endl;
}
return out;
}
// Prefix. Increment immediately and return the object.
Matrix& operator++(Matrix& mat) {
cout << "Prefix ++ operator" << endl;
// Increment all elements in the object by 1
for (int i = 0; i < mat.rows; i++) {
for (int j = 0; j < mat.cols; j++) {
mat.elements[i][j] += 1;
}
}
return mat;
}
// Postfix. Return the current object and "save" the incremented.
Matrix& operator++(Matrix& mat, int x) {
cout << "Postfix ++ operator" << endl;
// Save the current values
Matrix* curVals = new Matrix(mat);
// Increment the object
++(mat);
// Return the unincremented values
return *curVals;
}

test++ increments the value of test, so that it will point to the memory after your Matrix object. You need to dereference the pointer to get a Matrix object, then apply the increment to that.
What you want is (*test)++ or ++*test.

Related

Can't figure out why overloaded operator[] isn't getting called

I got a class Matrix and a class Row. Matrix has as member variable a pointer to a pointer of an object from class Row. I overloaded the operator [] for Matrix and Row. But somehow the overloaded operator from Row is never getting called and I can't figure out why not.
Example Code:
matrix.h
class Row
{
int* value;
int size;
public:
int& operator[](int i)
{
assert(i >= 0 && i < size);
return value[i];
}
};
class Matrix
{
private:
Row **mat; // Pointer to "Row"-Vector
int nrows, ncols; // Row- and Columnnumber
public:
Row& Matrix::operator[](int i){
assert(i >= 0 && i < nrows);
return *mat[i];
}
Row** getMat() {
return mat;
}
// Constructor
Matrix(int rows, int cols, int value);
};
matrix.cpp
#include "matrix.h"
Matrix::Matrix(int rows, int cols, int value) : nrows(rows), ncols(cols){
mat = new Row*[rows];
for(int i = 0; i < rows; i++) {
mat[i] = new Row(ncols);
for(int j = 0; j < ncols; j++){
// the operator-overload of Row[] isn't getting called and I don't get why not
mat[i][j] = value;
}
}
}
int main(){
Matrix m = new Matrix(2, 2, 4);
return 0;
mat[i] gives you Row*, and you want to call Row::operator[], but pointer to Row is not dereferenced automatically. So you have to dereference it manually: (*mat[i])[j].
So I just figured it out myself.
I tried to call the []-operator from Matrix through mat[][], but since mat is a Row** Row& Matrix::operator[](int i) is never getting called.

CPP: Matrix Destructor

For the following mymatrix class definition, why don't I need the commented parts of the destructor? Don't we need to delete what the a pointer points to as well? Or is it because we deleted all the meaningful data that we don't need these (commented-out) parts of the destructor?
template<typename T>
class mymatrix
{
private:
struct ROW
{
T* Cols; // dynamic array of column elements
int NumCols; // total # of columns (0..NumCols-1)
};
ROW* Rows; // dynamic array of ROWs
int NumRows; // total # of rows (0..NumRows-1)
}
Destructor:
virtual ~mymatrix()
{
for(int r=0;r<numRows;r++)
{
for(int c=0;c<Rows[r].NumCols;c++)
{
delete Rows[r].Cols[c];
}
// delete Rows[r];
}
// delete Rows;
}
Constructor:
mymatrix(int R, int C)
{
if (R < 1)
throw invalid_argument("mymatrix::constructor: # of rows");
if (C < 1)
throw invalid_argument("mymatrix::constructor: # of cols");
Rows = new ROW[R]; // an array with R ROW structs:
NumRows = R;
//intialize each row to C columns
for(int r=0;r<R;r++){
Rows[r].Cols=new T[C];
Rows[r].NumCols=C;
//initialize elements to their default value
for(int c=0;c<Rows[r].NumCols;c++){
Rows[r].Cols[c]=T{}; // default value for type T;
}
}
}
You need to use array-delete syntax because you are deleting arrays, not single objects:
delete[] Rows[r].Cols
...
delete[] Rows
Edit: I originally simply included the correct delete[] operator usage and left everything unchanged in my original example for brevity, but as #idclev463035818 pointed out, whenever you define your own destructor, copy constructor, or copy assignment operator (especially when they involve dynamic memory allocation), you almost always need to have all three. Almost never do you want any one without the others because if you have raw pointers in your object, then they will be shallow-copied to the new objects being instantiated. Then later on, the destructors for each of these objects will be called and attempt to delete the same portions of memory multiple times, which is a major error. I've added these to the code example and make use of them in new tests in the main function.
Full code:
#include <iostream>
using namespace std;
template<typename T>
class mymatrix
{
public:
struct ROW
{
T* Cols; // dynamic array of column elements
int NumCols; // total # of columns (0..NumCols-1)
};
ROW* Rows; // dynamic array of ROWs
int NumRows; // total # of rows (0..NumRows-1)
public:
mymatrix(int R, int C)
{
init(R, C);
}
void init(int R, int C) {
if (R < 1)
throw "";//throw invalid_argument("mymatrix::constructor: # of rows");
if (C < 1)
throw "";//invalid_argument("mymatrix::constructor: # of cols");
Rows = new ROW[R]; // an array with R ROW structs:
NumRows = R;
//intialize each row to C columns
for (int r = 0; r < R; r++) {
Rows[r].Cols = new T[C];
Rows[r].NumCols = C;
//initialize elements to their default value
for (int c = 0; c < Rows[r].NumCols; c++) {
Rows[r].Cols[c] = T{}; // default value for type T;
}
}
}
mymatrix(const mymatrix& other) : mymatrix(other.NumRows, other.Rows[0].NumCols) {
for (int r = 0; r < NumRows; ++r) {
ROW& thisRow = Rows[r];
ROW& otherRow = other.Rows[r];
for (int c = 0; c < thisRow.NumCols; ++c) {
thisRow.Cols[c] = otherRow.Cols[c];
}
}
}
mymatrix& operator=(const mymatrix& other) {
if (other.NumRows != NumRows || other.Rows[0].NumCols != Rows[0].NumCols) {
clear();
init(other.NumRows, other.Rows[0].NumCols);
}
for (int r = 0; r < NumRows; ++r) {
ROW& thisRow = Rows[r];
ROW& otherRow = other.Rows[r];
for (int c = 0; c < thisRow.NumCols; ++c) {
thisRow.Cols[c] = otherRow.Cols[c];
}
}
return *this;
}
void clear() {
for (int r = 0; r < NumRows; r++)
{
delete[] Rows[r].Cols;
}
delete[] Rows;
Rows = NULL;
NumRows = 0;
}
virtual ~mymatrix()
{
clear();
}
};
int main() {
mymatrix<int> mat(5, 5);
mat.Rows[0].Cols[2] = 5;
mymatrix<int> matClone(mat);
cout << matClone.Rows[0].Cols[2] << endl;
matClone.Rows[0].Cols[1] = 8;
cout << mat.Rows[0].Cols[1] << endl;
mat = matClone;
cout << mat.Rows[0].Cols[1] << endl;
system("pause");
return 0;
}
I'm telling this every time I see the usage of new/delete in C++.
Please don't use new/delete in C++!
Here is a minimal example of how to create a matrix which will allocate and delete itself without any manual memory allocations.
#include <vector>
class Matrix : public std::vector<std::vector<int>> {
public:
Matrix(size_t numRows, size_t numCols)
: std::vector<std::vector<int>>(numRows, std::vector<int>(numCols, 0)) {}
size_t numRows() const { return size(); }
size_t numCols() const { return front().size(); }
};
int main() {
auto m = Matrix(5, 4);
return m[4][3];
}

_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)) error

I'm trying to figure out why my program fails when I run. So far when I run my program it fails on me. I debugged the error and it brings me to dbgdel.cpp. Line 32 " _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));". I've searched for the answer to no avail, but it has something to do with my memory leak?
Here is my header:
#include <iostream>
using namespace std;
namespace project
{
#ifndef MATRIX_H
#define MATRIX_H
typedef int* IntArrayPtr;
class Matrix
{
public:
friend ostream& operator<<(ostream& out, Matrix& object);
//friend istream& operator>>(istream& in, Matrix& theArray);
//Default Constructor
Matrix();
Matrix(int max_number_rows, int max_number_cols, int intial_value);
//Destructor
~Matrix();
//Copy Constructor
Matrix(const Matrix& right_side);
//Assignment Operator
Matrix& operator=(const Matrix& right_side);
void Clear();
int Rows();
int Columns();
bool GetCell(int x,int y, int& val);
bool SetCell(int x,int y, int val);
int getNumber(int r, int c);
//void Debug(ostream& out);
private:
int initialVal;
int rows;
int cols;
IntArrayPtr *m;
};
#endif
}
My implementation file:
#include <iostream>
#include "Matrix.h"
using namespace project;
using namespace std;
namespace project
{
Matrix::Matrix()
{
typedef int* IntArrayPtr;
IntArrayPtr *m = new IntArrayPtr[1];
for(int i = 0; i < 1; i++)
m[i] = new int[1];
for(int r = 0; r < 1; r++)
for(int c = 0; c < 1;c++)
m[r][c] = 0;
}
Matrix::Matrix(int max_number_rows, int max_number_cols, int initial_value)
{
initialVal = initial_value;
rows = max_number_rows;
cols = max_number_cols;
IntArrayPtr *m = new IntArrayPtr[rows];
for(int i = 0; i < rows; i++)
m[i] = new int[cols];
for(int r = 0; r < max_number_rows; r++)
for(int c = 0; c < max_number_cols;c++)
m[r][c] = initial_value;
}
Matrix::~Matrix()
{
for(int i = 0; i <= rows; i++)
delete [] m[i];
delete [] m;
}
void Matrix::Clear()
{
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols;c++)
m[r][c] = initialVal;
}
int Matrix::Rows()
{
return rows;
}
int Matrix::Columns()
{
return cols;
}
bool Matrix::GetCell(int x,int y, int& val)
{
if(x < rows || y < cols)
return false;
else
{
val = m[x - 1][y - 1];
return true;
}
}
bool Matrix::SetCell(int x, int y, int val)
{
if(x < rows || y < cols)
return false;
else
{
m[x - 1][y - 1] = val;
return true;
}
}
int Matrix::getNumber(int r, int c)
{
return m[r][c];
}
ostream& operator<<(ostream& out, Matrix& object)
{
for(int r = 0; r < object.rows; r++)
{
for(int c = 0; c < object.cols; c++)
{
out << " " << object.m[r][c];
}
out << endl;
}
return out;
}
Matrix& Matrix::operator=(const Matrix& right_side)
{
if (this != &right_side)
{
rows = right_side.rows;
cols = right_side.cols;
delete[] m;
IntArrayPtr *m = new IntArrayPtr[rows];
for(int i = 0; i < rows; i++)
m[i] = new int[cols];
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols;c++)
m[r][c] = right_side.initialVal;
}
return *this;
}
/*
void Matrix::Debug(ostream& out)
{
out << "Number of rows = " << rows << endl;
out << "Number of columns = " << cols << endl;
out << "Initializer = " << initialVal << endl;
out << "Current contents of the matrix: " << endl;
out << m << endl;
}
*/
/*
istream& operator >>(istream& in, Matrix& theArray)
{
in >>
}
void interfaceMatrix()
{
int userChoice, rows, columns, value;
cout << "Default matrix or custom(1 for default, 0 for custom): ";
cin >> userChoice;
if (userChoice == 1)
{
Matrix object;
return object;
}
else if(userChoice == 0)
{
cout << "Enter number of rows: ";
cin >> rows;
cout << "Enter number of columns: ";
cin >> columns;
cout << "Enter initial value of each element: ";
cin >> value;
if(rows <= 0 || columns <= 0)
{
cout << "Invalid input." << endl;
exit(1);
}
else
{
Matrix object(rows, columns, value);
return object;
}
}
else
{
cout << "Invalid choice." << endl;
exit(1);
}
}
*/
}
In my driver I just put Matrix test(2,2,2), so I can create a 2 x 2 array with initial value of 2 for each element. I get the above error.
You are allocating rows number of rows, but deallocating rows+1 number of rows.
Check the destructor. <= must be <.
Besides this there are a lot of other [potential] errors in your code:
you are setting the local m variable instead of setting the m data member of your class (that's why I have the convention to always precede data members by m_ to prevent this kind of confusion). This error appears both in the constructor and the assignment operator.
you use rows to allocate the matrix, but max_number_rows to initialize the matrix. Although it works correctly now, it may lead to errors if row is initialized differently later (e.g. if row is initialized with std::max(max_number_rows,1000). Your code in the assignment operator is better.
your if-test in GetCell and SetCell is incorrect. It should probably be >= instead of <
the assignment operator copies the size of the matrix, but assigns all cells an initialValue. This is not an assignment. This implementation might/will confuse the rest of the code.
the typedef of IntArrayPtr is unnecessary
two issues:
You are not allocating any value into the "m" member of your object, you are allocating into local variables named "m"
you are over deallocating by looping from i=0 to i <= rows, you want i=0 to i < rows

The best way to free the memory in static function

This is a Matrix implementation which is working now.
And I need to deallocate the memory of the *data .
But the readMatrix function is static, so I cannot delete [] the data in readMatrix.
What is the best way to do it after the readMatrix returned the *m matrix.
Matrix.cpp
#include "Matrix.h"
#include <sstream>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
Matrix::Matrix(int i, int j) {
rows=i;
cols=j;
data = new float [i * j];
}
Matrix::Matrix(const Matrix& m) {
rows=m.rows;
cols=m.cols;
data=m.data;
}
int Matrix::numRows() {
return rows;
}
int Matrix::numCols() {
return cols;
}
float *Matrix::access(const int i, const int j) const {
return &data[(((i * cols) + j) - 1)] ;
}
std::ostream& operator<<(std::ostream &os, Matrix &m) {
int i, j;
os << m.numRows() << " " << m.numCols() <<endl;
for (i = 0; i < m.numRows(); i++) {
for (j = 0; j < m.numCols(); j++) {
os << *(m.access(i, j)) << " ";
}
os << endl;
}
return os;
}
int **Create2D(int row, int col)
{
int **p = new int* [row];
for (int j = 0; j < row; j ++)
p[j] = new int[col];
return p;
}
// Deletes an array pointed by 'p' that has 'row' number rows
void Delete2D(int **p, int row)
{
for (int j = 0; j < row; j ++)
delete [] p[j];
delete [] p;
}
Matrix Matrix::readMatrix(std::string filename)
{
int r ,c;
ifstream matrixFile(filename.c_str());
matrixFile >> r >> c;
int **p = Create2D(r, c);
Matrix* m = new Matrix(r, c);
for (int i=0; i<r; i++) {
for (int j=0; j<c; j++) {
matrixFile >> p[i][j];
*(m->access(i,j))= (float)p[i][j];
}
}
matrixFile.close();
Delete2D(p, r);
return *m;
}
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <stdlib.h>
#include <iostream>
#include <fstream>
class Matrix {
public:
Matrix(int i, int j) ;
Matrix (const Matrix& m) ;
int numRows ( ) ;
int numCols ( ) ;
float *access(const int i, const int j) const ;
friend std::ostream& operator<<(std::ostream &os, Matrix &m) ;
static Matrix readMatrix ( std::string filename ) ;
private:
Matrix() { }
// ~Matrix() { }
int rows ;
int cols ;
float *data ;
} ;
#endif // MATRIX_H
Thank you!
This here
Matrix::Matrix(const Matrix& m) {
rows=m.rows;
cols=m.cols;
data=m.data;
}
will not work well with your bare float pointer (note that it should be a float**), you end up having more instances pointing to the same data and when they go out of scope they will be deleting the same data more than once causing UB.
What you need to do in a copy constructor is to clone the data. Since you have the rows / cols it should be fairly easy.
now to your question.
This here
...
matrixFile >> p[i][j];
*(m->access(i,j))= (float)p[i][j];
...
(note that you declared access with const at the end (float *access(const int i, const int j) const), this means that the above assignment is illegal, const after the method means the instance will not be affected but you are using it to assign it a value)
seems unnecessary since you are reading one float at a time, it would be enough just to have a single float variable which you use to read the value from the file then assign your matrix that value
...
matrixFile >> floatRead;
*(m->access(i,j))= floatRead;
...
so just ditch the whole p matrix.
Alt. read in the values in the p matrix then let the Matrix instance m take ownership of it.
e.g.
...
m->attachMatrixValues(p);
...

C++ Overloading << operator in Matrix class

I am trying to overload the ostream << operator in my Matrix class, but I keep getting the following error:
Expected constructor, destructor, or type conversion before token &
Matrix::ostream& operator<<(const Matrix& matrix)
{
for (int r = 0; r < matrix.getNumrows(); r++)
{
cout << matrix.getPoint(r, 0);
for (int c = 0; c < matrix.getNumcolumns(); c++)
{
cout << " " << matrix.getPoint(r,c);
}
cout << endl;
}
return stream;
}
This is the rest of my class
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "Matrix.h"
using namespace std;
Matrix::Matrix()
{
}
Matrix::Matrix(int rows, int cols) {
numRows=rows;
numCols=cols;
//col=new double[cols];
mx=new double*[rows];
for ( int i=0; i < rows; i++ ) {
mx[i] = new double[cols];
// initalize each element of the new row.
for ( int c=0; c < cols; c++ ) {
mx[i][c] = 0.0;
}
}
}
Matrix::Matrix(const Matrix &theMatrix) {
int rows=theMatrix.numRows;
int cols=theMatrix.numCols;
numRows = rows;
numCols = cols;
mx=new double*[rows];
for ( int r=0; r < rows; r++ ) {
mx[r] = new double[cols];
// copy each element of the new row.
for ( int c=0; c < cols; c++ ) {
mx[r][c] = theMatrix.mx[r][c];
}
}
}
void Matrix::setMatrix(string file)
{
/* read the file */
fstream inputStream(file.c_str());
if(inputStream.is_open() )
{
string line;
stringstream ss;
getline(inputStream, line);
ss.clear();
ss.str(line);
ss >> numRows >> numCols;
mx=new double*[numRows];
for ( int i=0; i < numRows; i++ ) {
mx[i] = new double[numCols];
// initalize each element of the new row.
for ( int c=0; c < numCols; c++ ) {
mx[i][c] = 0.0;
}
}
//now loop to get values
for(int row=0; row<numRows; row++)
{
getline(inputStream, line);
ss.clear();
ss.str(line);
//now get every value in the line
for(int col=0; col<numCols; col++)
{
double current;
ss >> current;
mx[row][col] = current;
}//end reading values of row
}//end reading rows
}
//close the file
inputStream.close();
}
int Matrix::getNumrows()
{
return numRows;
}
int Matrix::getNumcolumns()
{
return numCols;
}
void Matrix::printPoint()
{
for ( int r=0; r < numRows; r++ )
{
for ( int c=0; c < numCols; c++ )
{
cout << mx[r][c] << " ";
}
cout << endl;
}
cout << endl;
}
bool Matrix::getIsSquared()
{
if( numRows == numCols )
{
return true;
}
else
{
return false;
}
}
double Matrix::det()
{
double det=0.0;
if(numRows!=numCols)
{
cout << "Number Rows must be same as number Colums\n";
}
if(numRows==2)
{
det=(mx[0][0]*mx[1][1])-(mx[0][1]*mx[1][0]);
}
else
{
for(int i=0 ; i<numCols ; i++)
{
Matrix temp(numRows-1,numCols-1);
for(int j=0 ; j<numRows-1 ; j++)
{
for(int k=0 ; k<numCols-1 ; k++)
{
if(k<i)
temp.mx[j][k]=mx[j+1][k];
else
temp.mx[j][k]=mx[j+1][k+1];
}
}
det+=pow(-1.0,i)*mx[0][i]*temp.det();
}
}
return det;
}
double Matrix::getPoint(int row, int col)
{
return mx[row][col];
}
Matrix Matrix::operator +(const Matrix &right) const
{
Matrix result(numRows,numCols);
if ( right.numRows != numRows || right.numCols != numCols )
{
cout << "\nError while adding matricies, the two must have the same dimentions.\n";
}
else
{
for ( int r=0; r < numRows; r++ )
{
for ( int c=0; c < numCols; c++ )
{
result.mx[r][c] = (this->mx[r][c]) + (right.mx[r][c]);
}
}
}
return result;
}
If you want to overload the ostream operator<< for your class, you need to use either a friend function or a non-member function because the ostream object appears on the left-hand side of the expression (it's written as os << my_matrix).
std::ostream& operator<<(std::ostream& os, const Matrix& matrix) { /* ... */ }
It looks like you are trying to implement it as a member function, but that should actually look like:
std::ostream& Matrix::operator<<(const Matrix& matrix) { /* ... */ }
This won't work because when you implement an operator overload as a member function, the type of the object on the left hand side of the expression is the same as the type of the class of which the overload is a member (so, in this case, you'd have to write my_matrix1 << my_matrix2, which isn't what you want).
Inside of the overload, you shouldn't write to cout directly; you should write to the ostream object that is passed as an argument to the function.
Write it as:
ostream& operator<<(ostream& os, const Matrix& matrix)
{
for (int r = 0; r < matrix.getNumrows(); r++)
{
os << matrix.getPoint(r, 0);
for (int c = 0; c < matrix.getNumcolumns(); c++)
{
os << " " << matrix.getPoint(r,c);
}
os << endl;
}
return os;
}
and it will work. It does not have to be a member function of Matrix.
Just change
Matrix::ostream& operator<<(const Matrix& matrix)
to
std::ostream& operator<< (std::ostream &stream, const Matrix &matrix)
It'll be a stand-alone function .. and should work just fine.