Expected { at the end of output - c++

I am trying to run my code from past few days but these errors are just not going away. The code is running smoothly in Code blocks but generating errors in Linux.
The errors are:
Matrix.h:14:20: error: expected ‘)’ before ‘rows’
Matrix(std::size_t rows, std::size_t cols, double initValue)
^~~~
Matrix.h:234:2: error: expected ‘}’ at end of input
};
^
Matrix.h:10:20: error: expected unqualified-id at end of input
double *p = nullptr;
I have already checked the semi colons and brackets and they seem to be all right.
My code is
#ifndef MATRIX_H
#define MATRIX_H
class Matrix
{
private:
int r, c, z;
double *p = nullptr;
public:
Matrix(std::size_t rows, std::size_t cols, double initValue)
{
r = rows;
c = cols;
z = r*c;
p = new double [z];
for(int i=0; i<z; ++i)
{
p[i]=initValue;
//cout<< p[i];
}
}
~Matrix()
{
delete [] p;
}
Matrix(const Matrix& m1) : r(m1.r), c(m1.c), z(r*c)
{
p = new double [z];
for (int i=0; i<z; ++i)
{
p[i]=m1.p[i];
}
}
//= operator overloading
Matrix& operator=(const Matrix& m1)
{
if (*this == m1)
return *this;
else
{
r= m1.r;
c=m1.c;
z=r*c;
delete[] p;
p=nullptr;
p= new double[m1.z];
for(int i=0;i<z;++i)
{
p[i]=m1.p[i];
}
return *this;
}
}
double& operator()(std::size_t i, std::size_t j)
{
return p[i*c+j];
}
const double& operator()(std::size_t i, std::size_t j) const
{
return p[i*c+j];
}
bool operator ==(const Matrix& m1) const
{
if(r==m1.r && c==m1.c)
{
for(int i=0;i<z;++i)
{
if (p[i]!=m1.p[i])
{
return false;
}
}
}
else if(r!=m1.r || c!=m1.c)
{
return false;
}
return true;
}
bool operator !=(const Matrix& m1) const
{
if( r!=m1.r || c!=m1.c)
{
return true;
}
for(int i=0;i<m1.z;++i)
{
if (p[i]!= m1.p[i])
{
return true;
}
}
return false;
}
Matrix& operator +=(const Matrix& m1)
{
for(int i=0;i<z;++i)
{
p[i]=p[i]+m1.p[i];
}return *this;
}
Matrix operator +(const Matrix& m1) const
{
Matrix m3 (r,c,0);
for(int i=0;i<z;++i)
{
m3.p[i]=p[i]+m1.p[i];
}
return m3;
}
Matrix& operator -=(const Matrix& m1)
{
for(int i=0;i<z;++i)
{
p[i]=p[i]-m1.p[i];
}return *this;
}
Matrix operator -(const Matrix& m1) const
{
Matrix m3 (r,c,0);
for(int i=0;i<z;++i)
{
m3.p[i]=p[i]-m1.p[i];
}
return m3;
}
Matrix operator *(const Matrix& m1) const
{
Matrix m3 (r,m1.c,0);
double s=0; //temp
if(c==m1.r)
{
for(int i=0;i<r;++i)
{
for(int j=0;j<m1.c;++j)
{
for(int k=0;k<m1.r;++k)
{
s+=this-> operator()(i,k)*m1(k,j);
}
m3.p[i*(m1.c)+j]=s;
s=0;
}
}return m3;
}
else
{
std::cout<<"Matrices are not compatible";
}
}
Matrix& operator *=(const Matrix& m1)
{
/*Matrix m3 (r,m1.c,0);
double s=0; //temp
for(int i=0;i<r;++i)
{
for(int j=0;j<m1.c;++j)
{
for(int k=0;k<m1.r;++k)
{
s+=this-> operator()(i,k)*m1(k,j);
}
m3.p[i*(m1.c)+j]=s;
s=0;
}
}
*this=m3;*/
*this = *this *m1;
return *this;
}
std::size_t rows() const
{
return r;
}
std::size_t cols() const
{
return c;
}
friend std::ostream& operator <<(std::ostream& x, const Matrix& m1)
{
for( int i=0;i<m1.r;++i)
{
for(int j=0;j<m1.c;++j)
{
x<<m1.p[i*m1.c+j]<<"\t";
}
std::cout<<std::endl;
}return x;
}
friend std::istream& operator >>(std::istream& y, Matrix& m1)
{
{
for( int i=0;i<m1.r;++i)
{
for(int j=0;j<m1.c;++j)
{
y>>m1.p[i*m1.c+j];
}
}
return y;
}
}
};
#endif // MATRIX_H
Please do let me know as to where I am wrong or missing something! I am trying to run MatrixProduct.cpp for different test cases.
Thanks in Advance.

So, as much as it is fast and convenient to put code into a header, it almost always leads to compile errors that take longer to track down than the time it takes to create the standard .h and .cpp files, especially with this much code.
I'm not exactly sure where the problem was, but it may have been the Matrix::operator>>(). You'll be able to find errors like this by using an IDE like eclipse and pressing Ctrl-i to auto-indent the code. Also, please check that I didn't mess up any of your logic formatting it.
Also, there's some academic trick question about memory allocation for matrices. if I remember correctly, you are supposed to allocate all the memory at once and then use pointers to refer to the array elements. I could be wrong and I'm not going to go into it now. Something like:
int rows(10000);
int cols(10000);
double* _data = (double*) malloc(rows * cols * sizeof(double));
double** data = (double**) malloc(rows * sizeof(double*));
for(int i = 0; i < rows; i++) {
data[i] = _data + (cols * i);
}
Please note that I have no idea if the matrix math is correct
matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <istream>
#include <ostream>
class Matrix {
public:
Matrix(std::size_t rows, std::size_t cols, double initValue);
Matrix(const Matrix& m1);
~Matrix();
Matrix& operator=(const Matrix& m1);
double& operator()(std::size_t i, std::size_t j);
const double& operator()(std::size_t i, std::size_t j) const;
bool operator==(const Matrix& m1) const;
bool operator!=(const Matrix& m1) const;
Matrix& operator+=(const Matrix& m1);
Matrix operator+(const Matrix& m1) const;
Matrix& operator-=(const Matrix& m1);
Matrix operator-(const Matrix& m1) const;
Matrix operator*(const Matrix& m1) const;
Matrix& operator*=(const Matrix& m1);
std::size_t rows() const;
std::size_t cols() const;
friend std::ostream& operator<<(std::ostream& x, const Matrix& m1);
friend std::istream& operator>>(std::istream& y, Matrix& m1);
private:
int r, c, z;
double *p;
};
#endif
matrix.cpp
#include "matrix.h"
#include <iostream>
#include <istream>
#include <ostream>
Matrix::Matrix(std::size_t rows, std::size_t cols, double initValue) :
r(rows),
c(cols),
z(r * c) {
p = new double [z];
for(int i = 0; i < z; ++i) {
p[i] = initValue;
}
}
Matrix::Matrix(const Matrix& m1) :
r(m1.r),
c(m1.c),
z(r*c) {
p = new double [z];
for (int i=0; i<z; ++i) {
p[i]=m1.p[i];
}
}
Matrix::~Matrix() {
delete [] p;
}
Matrix& Matrix::operator=(const Matrix& m1) {
if (*this == m1) {
return *this;
} else {
r = m1.r;
c = m1.c;
z = r * c;
delete[] p;
p = nullptr;
p = new double[m1.z];
for(int i = 0; i < z; ++i) {
p[i] = m1.p[i];
}
return *this;
}
}
double& Matrix::operator()(std::size_t i, std::size_t j) {
return p[i*c+j];
}
const double& Matrix::operator()(std::size_t i, std::size_t j) const {
return p[i*c+j];
}
bool Matrix::operator==(const Matrix& m1) const {
if(r==m1.r && c==m1.c) {
for(int i=0;i<z;++i) {
if (p[i] != m1.p[i]) {
return false;
}
}
} else if(r != m1.r || c != m1.c) {
return false;
}
return true;
}
bool Matrix::operator!=(const Matrix& m1) const {
if( r != m1.r || c != m1.c) {
return true;
}
for(int i = 0; i < m1.z; ++i) {
if (p[i] != m1.p[i]) {
return true;
}
}
return false;
}
Matrix& Matrix::operator+=(const Matrix& m1) {
for(int i=0;i<z;++i) {
p[i] = p[i] + m1.p[i];
}
return *this;
}
Matrix Matrix::operator+(const Matrix& m1) const {
Matrix m3 (r,c,0);
for(int i=0;i<z;++i) {
m3.p[i] = p[i] + m1.p[i];
}
return m3;
}
Matrix& Matrix::operator-=(const Matrix& m1) {
for(int i=0;i<z;++i) {
p[i] = p[i] - m1.p[i];
}
return *this;
}
Matrix Matrix::operator-(const Matrix& m1) const {
Matrix m3 (r, c, 0);
for(int i=0;i<z;++i) {
m3.p[i] = p[i] - m1.p[i];
}
return m3;
}
Matrix Matrix::operator*(const Matrix& m1) const {
Matrix m3 (r, m1.c,0 );
double s = 0;
if(c == m1.r) {
for(int i = 0; i < r; ++i) {
for(int j = 0; j < m1.c; ++j) {
for(int k = 0; k < m1.r; ++k) {
s += this->operator()(i,k)*m1(k,j);
}
m3.p[i * (m1.c) + j] = s;
s = 0;
}
}
return m3;
} else {
std::cout << "Matrices are not compatible";
}
}
Matrix& Matrix::operator*=(const Matrix& m1) {
*this = *this *m1;
return *this;
}
std::size_t Matrix::rows() const {
return r;
}
std::size_t Matrix::cols() const {
return c;
}
std::ostream& operator<<(std::ostream& x, const Matrix& m1) {
for( int i=0;i<m1.r;++i) {
for(int j=0;j<m1.c;++j) {
x << m1.p[i*m1.c+j] << "\t";
}
std::cout << std::endl;
}
return x;
}
std::istream& operator>>(std::istream& y, Matrix& m1) {
for( int i=0;i<m1.r;++i) {
for(int j=0;j<m1.c;++j) {
y >> m1.p[i * m1.c + j];
}
}
return y;
}

Related

How can I sum two complex matrix in C++? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have a class for complex numbers whose data members are im (the imaginary part) and re (the real part). Now I want to sum 2 matrix that come from the class Matrix (A and B) and put the sum in another matrix (C). This is what I tried. Any advice?
The error I get is
no match for 'operator[]' (operand types are 'Matrix' and 'int')
inline Matrix& operator+(Matrix& A, Matrix& B)
{
Matrix *C = new Matrix;
C->rows = A.rows;
C->columns = A.columns;
for(int i = 0; i < A.rows; i++)
for(int j = 0; j < A.columns; j++)
C[i][j] = A[i][j] + B[i][j];
}
return **C;
}
Add a operator '+' inside class like:
Matrix Matrix::operator+(const Matrix &other){
Matrix result = Matrix<T>(rows, other.columns);
if (this->rows == other.columns && this->columns == other.rows) {
for (int i = 0; i < this->rows; i++) {
for (int j = 0; j < this->columns; j++) {
result.n[i][j] = other.n[i][j] + this->n[i][j];
}
}
}
return result;
}
And the operator '=' to copy the result
Matrix& Matrix::operator=(const Matrix &other ){
if(this->columns<=other.columns && this->rows<=other.rows){
for(int i=0;i<this->rows;i++){
for(int j=0;j<this->columns;j++){
this->n[i][j]=other.n[i][j];
}
}
return (*this);
}else{
printf("ERROR");
}
}
Here's a basic Matrix implementation you could use.
Compatible with std::complex or whatever you own type is, as long as it's copy-constructible (see the main() in the link below).
template<class T>
struct Matrix {
std::vector<T> data;
size_t rows, cols;
Matrix(size_t rows_, size_t cols_, T value=T())
: data(rows_*cols_, value)
, rows(rows_)
, cols(cols_)
{
}
Matrix() = default;
Matrix(const Matrix& other) = default;
Matrix& operator=(const Matrix& other) = default;
Matrix(Matrix&& other) = default;
Matrix& operator=(Matrix&& other) = default;
T& operator()(size_t row, size_t col) {
return data.at(flatIndex(row, col));
}
const T& operator()(size_t row, size_t col) const {
return data.at(flatIndex(row, col));
}
Matrix operator+(const Matrix& other) const {
assert(data.size() == other.data.size());
assert(rows == other.rows);
assert(cols == other.cols);
Matrix sum = *this;
for (size_t i=0; i<data.size(); i++) {
sum.data.at(i) += other.data.at(i);
}
return sum;
}
protected:
size_t flatIndex(size_t row, size_t col) const {
return row * cols + col;
}
};
template<class T>
std::ostream& operator<<(std::ostream& os, const Matrix<T>& m) {
for (size_t r = 0; r<m.rows; r++) {
for (size_t c = 0; c<m.cols; c++) {
os << m(r, c) << " ";
}
os << '\n';
}
return os;
}
https://godbolt.org/z/Gvx5ac
If you really need performant/safe matrices, consider using a LinAlg library instead, like Eigen.

No match for operator*=

I've been working on a project in school that has been giving me some compiling issues and was wondering if I could have a second set of eyes look at what I am doing incorrectly, the error I keep getting is in line 47 of my test file saying there is not a match for operator *= which is confusing the heck out of me. I'll include my .h (header) my .cc (implementation) and my test file.
#ifndef MATRIX_H
#define MATRIX_H
#include <iostream>
using namespace std;
class Matrix {
public:
// Construction
Matrix(int, int, double);
// Copy construction
Matrix(const Matrix& m);
// Destructor
~Matrix();
// Index operators
const double& operator()(int i, int j) const; //to work on const objects
double& operator()(int i, int j);
// Copy assignment operator
Matrix& operator=(const Matrix& m);
// Compound arithmetic operators
Matrix& operator+=(const Matrix& x);
Matrix& operator-=(const Matrix& x);
Matrix& operator*=(const Matrix& m);
Matrix& operator*=(double d); // scalar multiplication
// Output
void print(ostream& sout) const; //display the matrix onto output stream
// sout neatly
int ncols() const; //return the number of columns
int nrows() const; // return the number of rows
private:
int rows; // number of rows
int cols; // number of columns
double **element; //dynamic array to hold data
};
// Arithmetic operators are not members
Matrix operator+(const Matrix& l, const Matrix&r); // return l+r
Matrix operator-(const Matrix& l, const Matrix&r); // return l-r
Matrix operator*(const Matrix& l, const Matrix&r); // return l*r
Matrix operator*(double d, const Matrix& r); // return d*l
Matrix operator*(const Matrix& m, double d); // return l*d
// Overloaded stream insertion operator
ostream& operator<<(ostream& out, const Matrix& x);
#endif
Now this is my .cc implementation file
#include<iostream>
#include<cstdlib>
#include<stdexcept>
#include<cassert>
#include<iomanip>
#include"Matrix.h"
using namespace std;
Matrix::Matrix(int r=0, int c=0, double d=0.0) // default constructor to initialize everything to zero
{
rows=r;
cols=c;
element=new double*[r];
for(int i=0;i<r;++i){
element[i]=new double[c];}
for(int i=0; i<r; ++i){
for(int j=0; j<c; ++j){
element[i][j]=d;
}
}
}
Matrix::Matrix(const Matrix& m)
{
rows=m.rows;
cols=m.cols;
element=new double*[rows];
for(int i=0;i<rows;++i)
element[i]= new double[cols];
for(int i=0; i<rows;++i)
for(int j=0; j<cols;++j)
element[i][j]=m.element[i][j];
}
Matrix::~Matrix()
{
for (int i=0;i<rows;i++){
delete [] element[i];
}
delete [] element;
}
const double& Matrix::operator() (int i, int j) const
{
return element[i][j];
}
double& Matrix::operator()(int i, int j)
{
return element[i][j];
}
Matrix& Matrix::operator=(const Matrix& m)
{
if(this==&m){
return *this;
}
else if(rows !=m.rows || cols !=m.cols)
{
delete [] element;
rows=m.rows;
cols=m.cols;
element= new double*[rows];
for(int i=0; i<rows;i++){
element[i]=new double[cols];
}
}
return *this;}
Matrix& Matrix::operator+=(const Matrix& x)
{
for(int i=0; i<rows; ++i){
for(int j=0; j<cols; ++j){
element[i][j]+=x.element[i][j];
}
}
return *this;
}
Matrix& Matrix::operator-=(const Matrix& x)
{
for(int i=0; i<rows; ++i){
for(int j=0; j<cols; ++j){
element[i][j]-=x.element[i][j];
}
}
return *this;
}
Matrix& Matrix::operator*=(const Matrix& m)
{
Matrix temp( rows, m.cols);
for(int i=0; i<temp.rows; ++i){
for(int j=0; j<temp.cols; ++j){
for(int k=0; k<cols; ++k){
temp.element[i][j]+=(element[i][k]* m.element[k][j]);
}
}
}
return(*this=temp);
}
Matrix& Matrix::operator*=(double d)
{
for(int i=0; i<rows; ++i){
for(int j=0; j<cols; ++j){
element[i][j] *= d;
}
}
return *this;
}
void Matrix::print(ostream& sout) const
{
for (int i = 0; i < rows; ++i) {
sout << element[i][0];
for (int j = 1; j < cols; ++j) {
sout << " " << element[i][j];
}
sout << endl;
}
}
int Matrix::ncols() const
{
return cols;
}
int Matrix::nrows() const
{
return rows;
}
Matrix operator+(const Matrix& l, const Matrix&r)
{
Matrix temp(l);
return(temp+=r);
}
Matrix operator-(const Matrix& l, const Matrix&r)
{
Matrix temp(l);
return (temp -=r);
}
Matrix operator*(const Matrix& l, const Matrix&r)
{
Matrix temp(l);
return (temp*=r);
}
Matrix operator*(double d, const Matrix&r)
{
return(r*d);
}
Matrix operator*(const Matrix& m, double d)
{
Matrix temp(m);
return(temp*=d);
}
ostream& operator<<(ostream& out, const Matrix& x)
{
x.print(out);
return out;
}
Now this is my test file which where I try to compile gives me the error:
test_matrix.cc:47:13: error: no match for ‘operator*=’ (operand types are ‘std::ostream {aka std::basic_ostream}’ and ‘int’)
cout<
#include<iostream>
#include"Matrix.h"
#include"Matrix.cc"
using namespace std;
int main()
{
Matrix m1(3,3,2.0);
Matrix m2(3,3,3.0);
cout<<"****Testing readMatrixData, and overoladed <<"<<endl;
cout<<"Matrix m1 is:"<<endl;
cout<<m1;
cout<<"Matrix m2 is:"<<endl;
cout<<m2;
cout<<"****Testing index subscript operator"<<endl;
cout<<"m1(2,1) is "<<m1(2,1)<<endl;
cout<<"Now Set m1(2,1) to -19"<<endl;
m1(2,1)=-19;
cout<<"m1 has "<<m1.nrows()<<"rows."<<endl;
cout<<"m1 has "<<m1.ncols()<<"columns."<<endl;
cout<<"m1 is now:"<<endl;
cout<<m1;
Matrix m3=m1+m2;
cout<<"Matrix m3 = m1 + m2:"<<endl;
cout<<m3;
Matrix m4=m1-m2;
cout<<"Matrix m4 = m1 - m2:"<<endl;
cout<<m4;
Matrix m5=m3*m4;
cout<<"Matrix m5 = m3 * m4:"<<endl;
cout<<m5;
Matrix m6=m3;
cout<<"After m6 =m3 matrix m6 is:"<<endl;
cout<<m6;
cout<<"****Testing scalar multiplication"<<endl;
cout<<"m3 *= 2 and m3 is now:"<<endl;
cout<<m3 *= 2.0;
Matrix m7 = m3 * 2.0;
cout<<"****Testing matrix times a constant"<<endl;
cout<<"m7 = m3 * 2 and m7 is:"<<endl;
cout<<m7;
Matrix m8 = 2.0 * m3;
cout<<"****Testing a scalar times a matrix"<<endl;
cout<<"m8 = 2 * m3 and m8 is:"<<endl;
cout<<m8;
Matrix m9(2,2,2.0);
cout<<"Matrix m9 is"<<endl;
cout<<m9;
Matrix m10(2,2,1.0);
cout<<"Matrix m10 is"<<endl;
cout<<m10;
cout<<"Testing *= with m9 *= m10. m9 is:"<<endl;
m9= m9*=m10;
cout<<m9;
cout<<"Testing += with m9 += m10. m9 is:"<<endl;
m9=m9+=m10;
cout<<"Testing -= with m9 -= m10. m9 is:"<<endl;
m9=m9-=m10;
return 0;
}
error: no match for ‘operator*=’ (operand types are ‘std::ostream {aka std::basic_ostream}’ and ‘int’)
Operator *= has lower precedence than operator <<, hence, cout << m3 *= 2.0 is evaluated as (cout << m3) *= 2.0, which produces the error.
You need to use parentheses to get the required order of evaluation. E.g.:
cout << (m3 *= 2.0);

Checking the matrix size

I don't really know how to check the size of both matrices, if they are appropriate to be added.
Here's my code, which is currently running without errors:
matrix operator+(const matrix & mat){
matrix add;
add.mSize = mat.mSize;
add.mP = new int[add.mSize * add.mSize];
for(int i = 0; i < add.mSize * add.mSize; i++){
add.mP[i] = mP[i] + mat.mP[i];
}
return add;
}
A general 2d matrix has two different dimensions, rows and columns (unless it is the particular case of a square matrix).
In the general case, your code could be:
#include <stdexcept>
class matrix
{
public:
matrix(int rows, int columns) :
mRows(rows), mColumns(columns), mP(NULL)
{
mP = new double[mRows * mColumns];
for (int i = 0; i < mRows * mColumns; i++)
mP[i] = 0.0;
}
matrix(const matrix& other) :
mRows(other.mRows), mColumns(other.mColumns), mP(NULL)
{
mP = new double[mRows * mColumns];
for (int i = 0; i < mRows * mColumns; i++)
mP[i] = other.mP[i];
}
~matrix()
{
delete[] mP;
}
const double* operator[] (int row) const {
return &mP[row * mColumns];
}
double* operator[] (int row) {
return &mP[row * mColumns];
}
matrix& operator=(const matrix& other) {
if (this == &other) return *this;
if ((mRows != other.mRows) || (mColumns != other.mColumns)) throw std::invalid_argument( "dimensions don't match" );
for (int r = 0; r < mRows; r++) {
for (int c = 0; c < mColumns; c++) {
(*this)[r][c] = other[r][c];
}
}
return *this;
}
matrix& operator+=(const matrix& other) {
if ((mRows != other.mRows) || (mColumns != other.mColumns)) throw std::invalid_argument( "dimensions don't match" );
for (int r = 0; r < mRows; r++) {
for (int c = 0; c < mColumns; c++) {
(*this)[r][c] += other[r][c];
}
}
return *this;
}
private:
int mRows;
int mColumns;
double *mP;
};
inline matrix operator+(matrix lhs, const matrix& rhs)
{
lhs += rhs;
return lhs;
}

My own vector class

I am trying to create my own vector class. I want to overload the basic features of STL vector. My code is compiling by after testing it, a message "segmentation fault(core dumped is)" is shown. Could you show me where I can improve my code. Thank you in advance!
#include<iostream>
#include<fstream>
using namespace std;
class Vector
{
public:
Vector();
Vector(const Vector& vect);
~Vector();
Vector& operator =(const Vector& vect);
void insert(double element);
bool operator ==(const Vector& vect);
Vector& operator +(const Vector& vect);
Vector& operator -(const Vector& vect);
Vector& operator *(const Vector& vect);
int size();
double operator[](int num);
friend istream& operator >>(istream& input, Vector& vect);
friend ostream& operator <<(ostream& output, Vector& vect);
private:
double* data;
int num;
int max;
};
Vector:: Vector()
{
double* data = NULL;
int num = 0;
int max = 0;
}
Vector::Vector(const Vector& vect)// not sure if its correct
{
data = new double[vect.max];
memcpy(data, vect.data, sizeof(double) * vect.num);
num = vect.num;
max = vect.max;
}
Vector::~Vector()
{
if(data)
{
delete[] data;
data = 0;
}
}
void Vector:: insert(double element)
{
if(num < max)
{
*(data + num) = element;
}
else
{
double *tmp = new double[num * 2];
delete[] data;
*(data + num) = element;
max *= 2;
}
num++;
}
Vector& Vector:: operator = (const Vector& vect)// highly unlikely to be correct
{
if(this != &vect)
{
if(data)
{
delete[] data;
data = 0;
}
max = vect.max;
data = new double[max];
for(int i = 0; i < num; i++)
{
this->data[i] = vect.data[i];
}
}
return *this;
}
bool Vector:: operator ==(const Vector& vect)
{
bool isEqual = true;
if(this->num != vect.num)
{
isEqual = false;
}
for(int i = 0; i < num; i++)
{
if(this->data[i] != vect.data[i] )
{
isEqual = false;
}
}
return isEqual;
}
Vector& Vector:: operator +(const Vector& vect)
{
Vector result;
for (int i = 0; i < num; ++i)
{
result.insert(*(data + i) + *(vect.data + i));
}
return result;
}
Vector& Vector:: operator -(const Vector& vect)
{
Vector result;
for (int i = 0; i < num; ++i)
{
result.insert(*(data + i) - *(vect.data + i));
}
return result;
}
Vector& Vector::operator*(const Vector &vect)
{
Vector result;
for (int i = 0; i < num; ++i)
{
result.insert(*(data + i) * *(vect.data + i));
}
return result;
}
int Vector:: size()
{
return num;
}
double Vector::operator[](int num)
{
return *(data + num);
}
ostream &operator <<(ostream &output, Vector &vect)
{
output << "[";
for (int i = 0; i < vect.size(); ++i)
{
output << vect[i];
if (i < vect.size() - 1)
output << ",";
}
output << "]\n";
return output;
}
istream &operator >>(istream &input, Vector &vect)
{
double element;
input >> element;
vect.insert(element);
return input;
}
int main()
{
Vector vec;
for (int i = 0; i < 10; ++i)
{
vec.insert(i);
}
return 0;
}
Look closely at your insert function. Specifically at how you are re-sizing the array.

How to correctly overload + operator

I am trying to define a simple class to work with 2d matrices, called Matrix2D01, and having trouble with the + operator.
I have the += operator which is working fine,
Matrix2D01& Matrix2D01::operator+=(Matrix2D01& mat2) {
int i,j;
for (i=0;i<M;i++)
for (j=0;j<N;j++) mat[i][j]+=mat2[i][j];
return *this;
}
The + operator is defined:
Matrix2D01 Matrix2D01::operator+(Matrix2D01& mat2) {
Matrix2D01 result(1,1);
result=*this;
result+=mat2;
return result;
}
When i try to use the + operator, for example by
mat3=mat1+mat2;
the compiler gives an error:
../MatrixGames.cpp:17:12: error: no match for ‘operator=’ in ‘mat3 = Matrix2D01::operator+(Matrix2D01&)((* & mat2))’
If anyone can tell me what I'm doing wrong it will be greatly appreciated.
Thanks.
I also have a = operator defined,
Matrix2D01& Matrix2D01::operator=(Matrix2D01& mat2) {
if (this==&mat2) return *this;
int i,j;
for (i=0;i<M;i++) {
delete [] mat[i];
}
delete [] mat;
M=mat2.Dimensions()[0];
N=mat2.Dimensions()[1];
mat = new double* [M];
for (i=0;i<M;i++) {
mat[i]=new double [N];
}
for (i=0;i<M;i++)
for (j=0;j<M;j++)
mat[i][j]=mat2[i][j];
return *this;
}
here is a complete test case:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
using namespace std;
class Matrix2D01 {
protected:
int D;
double **mat;
int M,N;
public:
Matrix2D01(int m,int n);
Matrix2D01(int m,int n,double d);
~Matrix2D01();
vector <int> Dimensions() {vector <int> d(D,M); d[1]=N; return d;}
double* operator[](int i) {return mat[i];}
Matrix2D01& operator=(Matrix2D01& mat2);
Matrix2D01& operator+=(Matrix2D01& mat2);
Matrix2D01 operator+(Matrix2D01& mat2);
};
Matrix2D01::Matrix2D01(int m, int n) {
int i,j;
D=2;
M=m;
N=n;
mat = new double* [M];
for (i=0;i<M;i++) {
mat[i]=new double [N];
}
for (i=0;i<M;i++)
for (j=0;j<M;j++)
mat[i][j]=0;
}
Matrix2D01::Matrix2D01(int m, int n,double d) {
int i,j;
D=2;
M=m;
N=n;
mat = new double* [M];
for (i=0;i<M;i++) {
mat[i]=new double [N];
}
for (i=0;i<M;i++)
for (j=0;j<M;j++)
mat[i][j]=d;
}
Matrix2D01::~Matrix2D01() {
int i;
for (i=0;i<M;i++) {
delete [] mat[i];
}
delete [] mat;
}
Matrix2D01& Matrix2D01::operator=(Matrix2D01& mat2) {
if (this==&mat2) return *this;
int i,j;
for (i=0;i<M;i++) {
delete [] mat[i];
}
delete [] mat;
M=mat2.Dimensions()[0];
N=mat2.Dimensions()[1];
mat = new double* [M];
for (i=0;i<M;i++) {
mat[i]=new double [N];
}
for (i=0;i<M;i++)
for (j=0;j<M;j++)
mat[i][j]=mat2[i][j];
return *this;
}
Matrix2D01& Matrix2D01::operator+=(Matrix2D01& mat2) {
int i,j,M2,N2;
M2=mat2.Dimensions()[0];
N2=mat2.Dimensions()[1];
if ((M!=M2)||(N!=N2)) {
cout<<"error: attempted to add non-matching matrices";
return *this;
}
for (i=0;i<M;i++)
for (j=0;j<N;j++) mat[i][j]+=mat2[i][j];
return *this;
}
Matrix2D01 Matrix2D01::operator+(Matrix2D01& mat2) {
Matrix2D01 result(1,1);
result=*this;
result+=mat2;
return result;
}
int main() {
Matrix2D01 mat1(2,2,1);
Matrix2D01 mat2(2,2,2);
Matrix2D01 mat3(2,2,4);
mat3+=mat1;
mat3=mat1+mat2;
return 1;
}
Herb Sutter advocates the following canonical way to overload operator + (please read GotW, it is really well written and interesting):
Don't include operator + as a member function, instead make it a free function.
Pass one object by value and the other by const reference. This makes it possible to use move operators when you add to a temporary.
Implement in terms of operator +=:
Matrix2D01 operator+(Matrix2D01 a, const Matrix2D01 &b)
{
a += b;
return a;
}
I've posted the code of the Matrix class I had written for an assignment on Discrete Mathematics last Sem
Notice how the assignment operator and the copy constructor are implemented All you need to do is write an assignment operator (I'd recommend that you write a copy constructor as well)
#pragma once
#include <vector>
#include <istream>
#include <ostream>
class Matrix
{
private:
unsigned int rows, cols;
std::vector<std::vector<int> > matrix;
public:
// Creates a Matrix with the given dimensions and sets the default value of all the elements to 0
Matrix(unsigned int rows, unsigned int cols);
// Destructor
~Matrix();
// Converts the relation set into it's adjacency Matrix representation
static Matrix CreateFromRelationSet( std::vector<std::pair<int, int> > relationSet);
// Copy Constructor
Matrix(const Matrix& cSource);
// Assignment Operator
Matrix& operator=(const Matrix& cSource);
// Resets all the elements of the matrix to 0
void Reset();
// Resizes the matrix to the given size
void Resize(unsigned int rows, unsigned int cols);
// Returns the number of rows
unsigned int getRows();
// Returns the number of columns
unsigned int getCols();
// Returns the smallest element from the matrix
int getSmallestElement();
// Returns the greatest element from the matrix
int getGreatestElement();
// Returns true if element is found and sets the row and column
// Returns false if not found
bool getPosition(int element, int* i, int* j);
// Deletes a row from the Matrix
void DeleteRow(unsigned int row);
// Deletes a column from the Matrix
void DeleteColumn(unsigned int col);
// Returns the element at (i,j)
int& operator()(unsigned int i, unsigned j);
// Returns the element at (i,j). Use the () operators instead
int getElementAt(unsigned int i, unsigned j);
friend std::ostream& operator << (std::ostream& out, Matrix& m);
friend std::istream& operator >> (std::istream& in, Matrix& m);
Matrix operator + (Matrix M);
Matrix operator - (Matrix M);
Matrix operator * (Matrix M);
};
// For use with cin & cout
std::ostream& operator << (std::ostream& out, Matrix& m);
std::istream& operator >> (std::istream& in, Matrix& m);
#include "Matrix.h"
Matrix::Matrix(unsigned int rows, unsigned int cols)
{
this->rows = rows;
this->cols = cols;
matrix.resize(rows);
for(std::vector<int>& i: matrix)
i.resize(cols);
Reset();
}
Matrix::~Matrix()
{
}
// local helper function
int findMaxFromSet(std::vector<std::pair<int, int> > set)
{
int maxVal = 0;
for(unsigned int i = 0; i < set.size(); i ++)
{
int p = set[i].first > set[i].second ? set[i].first : set[i].second;
maxVal = maxVal > p ? maxVal : p;
}
return maxVal;
}
Matrix Matrix::CreateFromRelationSet (std::vector<std::pair<int, int> > relationSet)
{
int max = findMaxFromSet(relationSet);
Matrix M(max,max);
M.Reset();
for(auto i = relationSet.begin(); i != relationSet.end(); ++ i)
M(i->first - 1, i->second - 1) = 1;
return M;
}
void Matrix::Reset()
{
for (auto& i: matrix)
for(auto& j: i)
j = 0;
}
void Matrix::Resize(unsigned int rows, unsigned int cols)
{
matrix.resize(rows);
for(auto& i:matrix)
i.resize(cols);
}
unsigned int Matrix::getRows()
{
return rows;
}
unsigned int Matrix::getCols()
{
return cols;
}
Matrix::Matrix(const Matrix& cSource)
{
rows = cSource.rows;
cols = cSource.cols;
matrix = cSource.matrix;
}
bool Matrix::getPosition(int element, int* i, int* j)
{
for(unsigned int ii = 0; ii < getRows(); ii ++)
for(unsigned int jj = 0; jj < getCols(); jj ++)
if(matrix[ii][jj] == element)
{
*i = ii;
*j = jj;
return true;
}
return false;
}
Matrix& Matrix::operator=(const Matrix& cSource)
{
// check for self-assignment
if (this == &cSource)
return *this;
if(this->getRows() < cSource.rows)
{
this->rows = cSource.rows;
this->matrix.resize(cSource.rows);
}
if(this->getCols() < cSource.cols)
{
this->cols = cSource.cols;
for(auto& i:this->matrix)
i.resize(cSource.cols);
}
for(unsigned int i = 0; i < rows; i++)
for(unsigned int j = 0; j < cols; j++)
this->matrix[i][j] = const_cast<Matrix&>(cSource)(i,j);
return *this;
}
std::ostream& operator << (std::ostream& out, Matrix& m)
{
for(auto& i: m.matrix)
{
for(auto& j: i)
out<<j<<'\t';
out<<std::endl;
}
return out;
}
std::istream& operator >> (std::istream& in, Matrix& m)
{
for(auto& i: m.matrix)
for(auto& j: i)
in>>j;
return in;
}
Matrix Matrix::operator + (Matrix op)
{
// Find the rows and cols of the new matrix
unsigned int r = this->getRows() > op.getRows()?this->getRows():op.getRows();
unsigned int c = this->getCols() > op.getCols()?this->getCols():op.getCols();
// Create Matrices
Matrix A = *this;
Matrix B = op;
Matrix R(r,c);
// Assign values
for(unsigned int i = 0; i < A.rows; i++)
for(unsigned int j = 0; j < A.cols; j++)
R(i,j) = A(i,j) + B(i,j);
return R;
}
Matrix Matrix::operator - (Matrix op)
{
// Find the rows and cols of the new matrix
unsigned int r = this->getRows() > op.getRows()?this->getRows():op.getRows();
unsigned int c = this->getCols() > op.getCols()?this->getCols():op.getCols();
// Create Matrices
Matrix A = *this;
Matrix B = op;
Matrix R(r,c);
// Assign values
for(unsigned int i = 0; i < A.rows; i++)
for(unsigned int j = 0; j < A.cols; j++)
R(i,j) = A(i,j) - B(i,j);
return R;
}
Matrix Matrix::operator* (Matrix op)
{
Matrix A = *this;
Matrix B = op;
if(A.getCols() != B.getRows())
throw std::exception("Matrices cannot be multiplied");
Matrix M(A.getRows(), B.getCols());
for(unsigned int i=0 ; i<A.getRows() ; i++)
for(unsigned int j=0 ; j<B.getCols() ; j++)
for(unsigned int k=0 ; k<B.getRows() ; k++)
M(i,j) = M(i,j) + A(i,k) * B(k,j);
return M;
}
int& Matrix::operator()(unsigned int i, unsigned j)
{
return matrix[i][j];
}
int Matrix::getElementAt(unsigned int i, unsigned j)
{
return (*this)(i,j);
}
int Matrix::getSmallestElement()
{
int result = matrix[0][0];
for(auto i:matrix)
for(auto j : i)
if(j < result)
result = j;
return result;
}
int Matrix::getGreatestElement()
{
int result = matrix[0][0];
for(auto i:matrix)
for(auto j : i)
if(j > result)
result = j;
return result;
}
void Matrix::DeleteRow(unsigned int row)
{
matrix.erase(matrix.begin() + row);
rows --;
}
void Matrix::DeleteColumn(unsigned int col)
{
for(auto& i: matrix)
i.erase(i.begin() + col);
cols --;
}
UPDATE:
result=*this;
In your code you are trying to allocate result the value of *this using the assignment operator, but no assignment operator is defined and the compiler doesn't find a match
Writing an assignment operator overload will solve this issue.
And if you have a copy constructor you can do something like:
Matrix2D01 Matrix2D01::operator+(Matrix2D01& mat2) {
Matrix2D01 result = *this;
result+=mat2;
return result;
}
Writing Assignment Operators: http://www.learncpp.com/cpp-tutorial/912-shallow-vs-deep-copying/
And if you're interested in the details - here you go: http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
Your operands should be const references. Otherwise, you
can't use a temporary to initialize them. (In this case, the
return value of operator+ is a temporary, and thus, cannot be
bound to the non-const reference of operator=.)
If your operator+ is a member, it should be const as well.
After all, it doesn't modify the object it is called on. So:
Matrix2D01& Matrix2D01::operator=( Matrix2D01 const& mat2 );
Matrix2D01& Matrix2D01::operator+=( Matrix2D01 const& mat2 );
Matrix2D01 Matrix2D01::operator+( Matrix2D01 const& mat2 ) const;
Also, your assignment operator is broken. (Think of what will
happen, if one of the allocations fails after you've freed the
original data.) In general, if you have to test for self
assignment, the assignment operator is broken.