I created a class called Matrix with a 2D array. I can run it with the constructor, copy constructor and destructor. When I introduce the unary negation operator, I get a run time error.
https://gist.github.com/anonymous/7823794
#ifndef MATRIX_H
#define MATRIX_H
class Matrix
{
public:
Matrix(int rSize=3, int cSize=3);
Matrix(const Matrix& m);
~Matrix();
bool setValue(int rSize, int cSize, int value);
bool getValue(int rVal, int cVal, int& value)const;
const Matrix operator- ();
private:
int rowSize;
int columnSize;
int** arr;
};
#endif
#include<iostream>
#include"Matrix.h"
using namespace std;
Matrix::Matrix(int rSize,int cSize)
{
columnSize = cSize;
rowSize = rSize;
arr = new int* [rowSize];
for(int i=0; i<rowSize; i++)
arr[i] = new int[columnSize];
for(int j=0; j<rowSize; j++)
{
for(int k=0; k<columnSize; k++)
arr[j][k] = 0;
}
}
Matrix::Matrix(const Matrix& m)
{
columnSize = m.columnSize;
rowSize = m.rowSize;
arr = new int* [rowSize];
for(int i=0; i<rowSize; i++)
{
arr[i] = new int [columnSize];
}
for(int i=0; i<rowSize; i++)
{
for(int j=0; j<columnSize; j++)
arr[i][j] = m.arr[i][j];
}
}
Matrix::~Matrix()
{
for(int i = 0; i < rowSize; ++i)
delete [] arr[i];
delete [] arr;
}
bool Matrix::setValue(int rVal, int cVal, int value)
{
if((rVal<0)||(cVal<0)||(rVal>rowSize-1)||(cVal>columnSize-1))
return false;
arr[rVal][cVal] = value;
return true;
}
bool Matrix::getValue(int rVal, int cVal, int& value)const
{
if((rVal<0)||(cVal<0)||(rVal>rowSize-1)||(cVal>columnSize-1))
return false;
value = arr[rVal][cVal];
return true;
}
const Matrix Matrix:: operator- ()
{
Matrix m(*this);
for (int i = 0; i< rowSize; i++)
{
for(int j=0; j<columnSize; j++)
m.arr[i][j] = (this->arr[i][j])* -1 ;
}
return m;
}
#include<iostream>
#include"Matrix.h"
using namespace std;
void main()
{
Matrix m(4, 5);
Matrix m2(m);
m2.setValue(1,2,12);
int x;
m2.getValue(1,2,x);
Matrix m3;
m3 = -m2;
}
Edit: Following #unwind and #interjay advice, I implemented the assignment operator first and returned a value, not a reference, for the negation operator and it works. Thank you all for your help
You don't have an assignment operator in your class, which will cause double deletion of the member pointer after an assignment (and you're assigning in the line m3 = -m2;).
You should obey the rule of three.
unwind is also correct that the negation operator should return by value: You should never return a reference to a local variable from a function as that leads to undefined behavior.
Declaring the operator to return const Matrix& and then returning a local variable is wrong. That's a dangling reference, surely?
See for reference this answer where the operator returns an actual new value, not a reference. This makes a lot more sense to me.
Related
cannot convert 'brace-enclosed initializer list>' to 'int' in assignment
as explained above, line 19 and 20, specifically when I described the content of the array, the compiler told me the line above. I know it is a long code, and I will appreciate your answers.
I guess that's as detailed as I could.
#include <iostream>
using namespace std;
class matrix{
private:
static const int x =3;
int m1[x][x];
int m2[x][x];
int c[x][x];
public:
matrix(){
int m1[x][x];
int m2[x][x];
int c[x][x];
c[x][x];
}
matrix(int m1[x][x], int m2[x][x], int c[x][x]){
m1[x][x]= {{1,2,3},{4,5,6},{7,8,9}};
m2[x][x]= {{10,11,12},{13,14,15},{16,17,18}};
c[x][x];
}
matrix operator+(matrix& m2){
matrix result;
for( int i=0; i<x; i++){
for(int j=0; j<x; j++){
result.m1[i][j];
result.m2[i][j];
result.c[i][j] = result.m1[i][j] + result.m2[i][j];
}
}
return result;
}
matrix operator-(matrix& m2){
matrix result;
for( int i=0; i<x; i++){
for(int j=0; j<x; j++){
result.m1[i][j];
result.m2[i][j];
result.c[i][j] = result.m1[i][j] - result.m2[i][j];
}
}
return result;
}
matrix operator*(matrix& m2){
matrix result;
for( int i=0; i<x; i++){
for(int j=0; j<x; j++){
result.m1[i][j];
result.m2[i][j];
result.c[i][j] = result.m1[i][j] * result.m2[i][j];
}
}
return result;
}
friend ostream& operator <<(ostream& outs, const matrix& m){
outs << m<< endl;
return outs;
}
};
int main(){
matrix m1;
matrix m2;
cout <<m1+m2<<endl;
return 0;
}
As already said this code is just wrong from top to bottom. It really should be thrown away. Let fix the most basic error. class matrix represents a 3x3 matrix. So it should be written like this
class matrix
{
private:
static const int x = 3;
int elem[x][x]; // the elements of a 3x3 matrix
public:
... // more code
};
In your version
class matrix
{
private:
static const int x =3;
int m1[x][x];
int m2[x][x];
int c[x][x];
public:
... // more code
};
the class has three different 3x3 matrices. That isn't right.
So throw your code away, start again with class like the one I've written above.
Here's how operator+ looks with my version of the class
matrix operator+(const matrix& m2) {
matrix result;
for (int i=0; i<x; i++) {
for (int j=0; j<x; j++) {
result.elem[i][j] = elem[i][j] + m2.elem[i][j];
}
}
return result;
}
It's really hard to understand what you are trying to do, You have parameters in the constructor and then you are reinitializing them again.
But I can help you with the way to initialize 2d Matix using the initializer list
matrix():m1{{1,2}, {3, 4}} ,...{}
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.
Im trying to to use operator overloading with both + and = operator on a matrix class which i created. either the constructor or destructor is causing a problem or it isn't either (though i grayed out each of them and both and the code seems to work). could someone please help me understand what is causing this strange behavior. when i try to create 3 matrixes a b and c then try a = b+c; it just fails.
header file
#ifndef MATRIX_H;
#define MATRIX_H;
using namespace std;
enter code here
class matrix
{
friend ostream& operator<< (ostream&, matrix &);
public:
matrix();
matrix(int,int); //constructor
matrix(const matrix&);//copy constructor
~matrix();
int getRow();
int getCol();
void setRow(int);
void setCol(int);
class arr1D{ //proxy class to allow the use of [][] operator
public:
arr1D(int* a):temp(a){}
int &operator[](int a){
return temp[a];
}
int *temp;
};
arr1D operator[](int a){
return arr1D(arr2[a]);
}
matrix& operator=(const matrix& );
matrix& operator+(const matrix& );
protected:
private:
int row , col;
int **arr2;
};
#endif // MATRIX_H
enter code here
cpp file
#include <iostream>
#include "matrix.h"
using namespace std;
matrix::matrix()
{
setCol(0);
setRow(0);
**arr2=0;
}
matrix::matrix(int x, int y) //matrix constructor creates x*y matrix and initializes to 0's
{
setCol(y);
setRow(x);
arr2 = new int * [getRow()];
if (arr2) {
for (int i = 0; i < getRow(); i++) {
arr2[i] = new int [getCol()];
};
};
for (int i=0; i<getRow();i++){
for (int j=0;j<getCol();j++){
arr2[i][j]=0;
};
};
}
matrix::matrix(const matrix &m){ //defines the copying constructor
row=m.row;
col=m.col;
arr2 = new int*[row];
for (int i=0; i<row; i++){
arr2[i] = new int[col];
}
for (int i=0; i<row; i++){
for (int j=0; j<col; j++){
arr2[i][j] = m.arr2[i][j];
}
}
}
matrix::~matrix(){ //defines the destructor
for (int i=0; i<row; i++){
delete[] arr2[i];
}
delete[] arr2;
}
int matrix::getRow(){ //getter for row
return row;
}
int matrix::getCol(){ // getter for col
return col;
}
void matrix::setRow(int x){ //setter for row
row=x;
}
void matrix::setCol(int x){ //setter for col
col=x;
}
ostream& operator<< (ostream& output, matrix& a){
int i,j;
for (i=0; i < a.getRow() ; i++){
for (j=0; j< a.getCol() ; j++){
output << " " <<a.arr2[i][j];
};
output << "\n";
};
return output;
}
matrix& matrix::operator=(const matrix& right)
{
if (this == &right) { // Same object?
return *this;
}
row = right.row;
col = right.col;
for (int i=0; i<row; i++)
{
for (int j=0; j<col; j++){
arr2[i][j]=right.arr2[i][j];
}
}
return *this ;
}
matrix& matrix::operator+(const matrix& right)
{
int row=right.row;
int col=right.col;
matrix result(row,col);
for (int i = 0; i < row; i++){
for (int j = 0; j < col; j++){
//cout<<"arr2[i][j]="<<arr2[i][j]<<endl;
//cout<<"right.arr2[i][j]="<<right.arr2[i][j]<<endl;
result.arr2[i][j]=(arr2[i][j] + right.arr2[i][j]);
//cout<<"result.arr2[i][j]="<<result.arr2[i][j]<<endl;
};
};
return result;
}
First, as the other answer pointed out, you are returning a reference to a temporary in your operator +. That is undefined behavior.
But instead of writing operator + in this fashion, what you should do is write operator += instead, and then in turn, write operator + in terms of operator +=. Since a programmer would expect += to also work for the matrix in addition to +, it makes no sense to leave out +=.
For operator +=, you would in this case return a reference to the current object.
So all we need to do is move the code in operator + to operator +=:
#include <exception>
//...
matrix& matrix::operator+=(const matrix& right)
{
if(row != right.row || col != right.col)
throw std::logic_error("Matrix not the same size");
for (int i = 0; i < right.row; i++)
{
for (int j = 0; j < right.col; j++)
arr2[i][j] += right.arr2[i][j]);
}
return *this;
}
Note that we return a reference to the current matrix, since += modifies the current matrix. Also note that we throw an exception on an illegal matrix being sent to +=. This IMO makes more sense than returning a legitimate matrix back on error. If the matrix is not the same size, the code should not try and return a matrix back.
Now operator + can be written in terms of +=:
matrix matrix::operator+(const matrix& right)
{
return matrix(*this) += right;
}
Believe it or not, that's it. All we did was create a temporary matrix and call += with the passed in argument. We return the result of this as a brand new matrix, just as we expect.
The other issue is the assignment operator. Given that you've written a copy constructor and destructor, and the copy constructor works without having to use the assignment operator, then the copy / swap idiom can be used to implement the assignment operator.
#include <algorithm>
//...
matrix& matrix::operator=(const matrix& right)
{
matrix temp(right);
std::swap(temp.arr2, arr2);
std::swap(temp.row, row);
std::swap(temp.col. col);
return *this;
}
All we did here was create a temporary matrix of the passed in object and swap out its contents with the current object's contents. When the temporary dies off at the return, the temporary destroys the old contents that were swapped out.
This method has the advantage of not only being very simple to implement (just a bunch of calls to std::swap), it is also exception safe. If there is an issue creating the temporary matrix, a std::bad_alloc exception would have been thrown, without messing up or altering any members of this. The issue with the other answer given, where you're deallocating the memory first before allocating the new memory, is solved by using the above technique.
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.
//output is "01234 00000" but the output should be or what I want it to be is
// "01234 01234" because of the assignment overloaded operator
#include <iostream>
using namespace std;
class IntArray
{
public:
IntArray() : size(10), used(0) { a= new int[10]; }
IntArray(int s) : size(s), used(0) { a= new int[s]; }
int& operator[]( int index );
IntArray& operator =( const IntArray& rightside );
~IntArray() { delete [] a; }
private:
int *a;
int size;
int used;//for array position
};
int main()
{
IntArray copy;
if( 2>1)
{
IntArray arr(5);
for( int k=0; k<5; k++)
arr[k]=k;
copy = arr;
for( int j=0; j<5; j++)
cout<<arr[j];
}
cout<<" ";
for( int j=0; j<5; j++)
cout<<copy[j];
return 0;
}
int& IntArray::operator[]( int index )
{
if( index >= size )
cout<<"ilegal index in IntArray"<<endl;
return a[index];
}
IntArray& IntArray::operator =( const IntArray& rightside )
{
if( size != rightside.size )//also checks if on both side same object
{
delete [] a;
a= new int[rightside.size];
}
size=rightside.size;
used=rightside.used;
for( int i = 0; i < used; i++ )
a[i]=rightside.a[i];
return *this;
}
I think that the problem is that nowhere in your code sets used to anything other than 0 so when you loop from 0 to used nothing is copied.
Do you mean to set used when you assign to an element in operator[] ?
Also, if it's necessary to define a destructor and a copy-assignment operator then you usually (and in this case) need to supply a copy-constructor as well.