operator[] overloading for a const reference two-dimension pointer - c++

To overload an "+" operator for const matrix, I use the "[]"
Matrix const operator+(const Matrix & mat1, const Matrix & mat2)
{
Matrix sum(mat1);
if (sum.height != mat2.height || sum.width != mat2.width)
cout << "Dimension error!";
else {
for (int i = 0; i < sum.height; i++)
for (int j = 0; j < sum.width; j++)
sum[i][j] = mat2[i][j];
}
return sum;
}
So, I define the overloading for []
(const int*)& operator[] (int i) const {
return (*this).ele[i + 1];
}
But the IDE report the error
"Error IntelliSense: a reference of type "const int *&" (not const-qualified) cannot be initialized with a value of type "int *"
How to solve this error? I have tried many times TAT.
And this is the entire code:
#define NULL 0
#include<iostream>
using namespace std;
class Matrix {
private:
int width, height;
int **ele;
public:
Matrix();
Matrix(int**);
Matrix(int, int);
Matrix(const Matrix&);
Matrix operator= (const Matrix&);
friend const Matrix operator+ (const Matrix&, const Matrix&);
friend const Matrix operator- (const Matrix&, const Matrix&);
(int*)& operator[] (int i) {
return (*this).ele[i + 1];
}
(const int*)& operator[] (int i) const {
return (*this).ele[i + 1];
}
};
Matrix::Matrix() {
width = 0; height = 0;
ele = NULL;
}
Matrix::Matrix(const Matrix& mat) {
Matrix(mat.height, mat.width);
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++) {
(*this)[i][j] = mat[i][j];
}
}
Matrix::Matrix(int** e) {
(*this).height = e[0][0];
(*this).width = e[0][1];
for (int i = 1; i < height; i++)
for (int j = 0; j < width; j++) {
(*this).ele[i][j] = e[i][j];
}
}
Matrix::Matrix(int height, int width) {
(*this).width = width;
(*this).height = height;
ele = new int*[height + 1];
ele[0] = new int[2];
ele[0][0] = height; ele[0][1] = width;
for (int i = 1; i < height + 1; i++)
{
ele[i] = new int[width];
}
for (int i = 1; i < height; i++)
for (int j = 0; j < width; j++) {
ele[i][j] = 0;
}
}
inline Matrix Matrix::operator=(const Matrix & mat)
{
Matrix tempMat(mat);
return tempMat;
}
Matrix const operator+(const Matrix & mat1, const Matrix & mat2)
{
Matrix sum(mat1);
if (sum.height != mat2.height || sum.width != mat2.width)
cout << "Dimension error!";
else {
for (int i = 0; i < sum.height; i++)
for (int j = 0; j < sum.width; j++)
sum[i][j] = mat2[i][j];
}
return sum;
}
Matrix const operator-(const Matrix & mat1, const Matrix & mat2)
{
Matrix diff(mat1);
if (diff.height != mat2.height || diff.width != mat2.width)
cout << "Demension error!";
else {
for (int i = 0; i < diff.height; i++)
for (int j = 0; j < diff.width; j++)
diff[i][j] = mat2[i][j];
}
return diff;
}

I have found your code compiled (g++ version 4.6.3) when removed parentheses from overloaded operators signature, like user remyabel said.
So try
int* operator[] (int i) {
return (*this).ele[i + 1];
}
const int* operator[] (int i) const {
return (*this).ele[i + 1];
}
instead of
(int*)& operator[] (int i) {
return (*this).ele[i + 1];
}
(const int*)& operator[] (int i) const {
return (*this).ele[i + 1];
}

Related

Understanding the code to write an overload function (new int[] in matrix operations)

yesterday our lecturer got us this code below without any meaningful explanation. We are struggling to understand how it works.
class Matrix {
static int mem;
int rows, cols;
int* ptr;
public:
Matrix(int l = 10, int k = 10) :rows(l), cols(k) {
ptr = new int[rows * cols];
mem += (rows * cols) * sizeof(int);
}
Matrix(const Matrix& x) :rows(x.rows), cols(x.cols) {
ptr = new int[rows * cols];
int* tmp = ptr; // HERE
mem += (rows * cols) * sizeof(int);
for (int i = 0; i < x.rows * x.cols; i++) {
ptr[i] = x.ptr[i];
}
}
~Matrix() {
mem -= (rows * cols) * sizeof(int);
delete[] ptr;
}
friend istream& operator>>(istream& input, Matrix& x) {
int* tmp = x.ptr;
for (int i = 0; i < x.rows; i++) {
for (int j = 0; j < x.cols; j++) {
input >> *tmp; tmp++;
}
}
return input;
}
friend ostream& operator<<(ostream& output, Matrix& x) {
int* tmp = x.ptr;
for (int i = 0; i < x.rows; i++) {
for (int j = 0; j < x.cols; j++) {
output << *tmp << " "; tmp++;
}
output << endl;
}
return output;
}
friend Matrix operator+(const Matrix& x, const Matrix& y) {
Matrix tmp(x.rows,x.cols);
if (x.rows != y.rows || x.cols != y.cols) {
return tmp;
}
else {
for (int i = 0; i < x.rows * x.cols; i++) {
tmp.ptr[i] = x.ptr[i] + y.ptr[i];
}
return tmp;
}
}
Matrix operator=(const Matrix& x) {
if (x.rows != x.cols) {
delete[] ptr;
rows = x.rows;
cols = x.cols;
ptr = new int[rows * cols];
mem += (rows * cols) * sizeof(int);
}
for (int i = 0; i < x.rows * x.cols; i++) {
ptr[i] = x.ptr[i];
}
return *this;
}
friend Matrix operator*(const Matrix& x, const Matrix& y) {...}
};
Based on this chunk of code we have to overload '*' operator that would multiply two matrices together (ex. C = A * B).
And when it's fairly easy to do with 2D arrays, I just can't wrap my head around the way it's working right now, so any help would be more than appreciated.
Thanks for your time!

Matrix class content using shared_ptr?

class Matrix
{
private:
int rows;
int cols;
int** Mat;
public:
Matrix(){}
Matrix(const int& rows, const int& cols):rows(rows),cols(cols)
{
Mat = new int* [cols];
for (int i = 0; i < rows; i++)
{
Mat[i] = new int[cols]();
}
}
Matrix operator +(const Matrix& other)const
{
Matrix temp(rows, cols);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
temp.Mat[i][j] += other.Mat[i][j] + Mat[i][j];
return temp;
}
My question is regarding how I'd use shared_ptr and make_shared to replace int** Mat? and, after that, how do I use it in the constructor and operator+? It's a custom matrix class that should add matrices
#include <iostream>
#include <memory>
#include <cassert>
class Matrix {
private:
int rows;
int cols;
std::shared_ptr<std::shared_ptr<int>> Mat;
public:
Matrix() = default;
Matrix(const int& rows, const int& cols) : rows(rows), cols(cols)
{
Mat.reset(new std::shared_ptr<int>[rows], [](std::shared_ptr<int>* p) { delete[] p; });
for (int i = 0; i < rows; ++i)
{
Mat.get()[i].reset(new int[cols], [](int* p) { delete[] p; });
}
for (int i = 0; i < (*this).rows; ++i)
for (int j = 0; j < (*this).cols; ++j)
(*this)[i][j] = 0;
}
int* operator[](const int& index) const
{
return Mat.get()[index].get();
}
Matrix(const Matrix& other) : cols(other.cols), rows(other.rows)
{
Mat.reset(new std::shared_ptr<int>[rows], [](std::shared_ptr<int>* p) { delete[] p; });
for (int i = 0; i < rows; ++i)
{
Mat.get()[i].reset(new int[other.cols], [](int* p) { delete[] p; });
}
for (int i = 0; i < other.rows; i++)
for (int j = 0; j < other.cols; j++)
(*this)[i][j] = other[i][j];
}
Matrix& operator=(const Matrix& other)
{
if (Mat != other.Mat && cols == other.cols && rows == other.rows)
{
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
(*this)[i][j] = other[i][j];
return *this;
}
else
return *this;
}
Matrix operator+(const Matrix& other) const
{
Matrix temp(rows, cols);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
temp[i][j] += other[i][j] + (*this)[i][j];
return temp;
}
friend std::ostream& operator<<(std::ostream& os, Matrix& m)
{
for (int i = 0; i < m.rows; ++i)
{
for (int j = 0; j < m.cols; ++j)
{
os << m[i][j] << " ";
}
os << std::endl;
}
return os;
}
};
int main()
{
Matrix a(2, 2);
a[0][0] = 1;
a[0][1] = 1;
std::cout << a << std::endl;
Matrix b(2, 2);
b[1][1] = 1;
b[1][0] = 1;
std::cout << b << std::endl;
b[1][0] = 9;
Matrix c(a);
c[0][0] = 6;
std::cout << c << std::endl;
Matrix d = b;
std::cout << d << std::endl;
Matrix e = a + b;
std::cout << e << std::endl;
}
I have solved it myself in the end :D

How to write a friend (operator) method in a template?

So I'm trying to overload the operator + in a template class.
the code compiles and runs but crashes at the use of the operator +.
tried so many things, I think it's a syntax problem? any advice would be appreciated!
The operator = is overloaded and works.
Matrix.h
template <int row, int col, class T = int>
class Matrix
{
int rows;
int cols;
T** mat;
public:
Matrix(int defVal = 0) {
rows = row;
cols = col;
memory();
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = defVal;
}
~Matrix() {
del();
}
Matrix(const Matrix& other) {
*this = other;
}
const Matrix& operator=(const Matrix& other) {
if (&other != this)
{
rows = other.rows;
cols = other.cols;
del();
memory();
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = other.mat[i][j];
}
return *this;
}
friend ostream& operator<<(ostream& os, const Matrix& m) {
for (int i = 0; i < m.cols; i++)
{
for (int j = 0; j < m.rows; j++)
os << m.mat[i][j] << " ";
os << endl;
}
return os;
}
friend Matrix operator+(const Matrix& other, T num) {
Matrix temp = other;
for (int i = 0; i < temp.rows; i++)
for (int j = 0; j < temp.cols; j++)
temp.mat[i][j] += num;
return temp;
}
void memory(){
mat = new T * [rows];
for (int i = 0; i < rows; i++)
mat[i] = new T[cols];
}
void del(){
for (int i = 0; i < rows; i++)
delete[] mat[i];
delete[] mat;
}
};
main.cpp
int main() {
Matrix<4, 4> mat;
std::cout << mat << std::endl;
Matrix<4, 4> identity(1);
std::cout << identity + 3 << std::endl; //crashes here
return 0;
}
if you need other parts of the code let me know! Thanks in advance!
Your copy constructor and assignment looks suspicious, you del after changing rows and cols, without initialising anything.
I expect it should be
Matrix(const Matrix& other) : rows(0), cols(0), mat(nullptr) {
*this = other;
}
const Matrix& operator=(const Matrix& other) {
if (&other != this)
{
del(); // clean up first
rows = other.rows;
cols = other.cols;
memory();
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = other.mat[i][j];
}
return *this;
}
As an aside, I wouldn't use dynamic allocation here at all, and instead
template <typename T, size_t rows, size_t cols>
class Matrix
{
std::array<std::array<T, cols>, rows> mat;
public:
Matrix(T defVal = {}) {
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = defVal;
}
friend std::ostream& operator<<(std::ostream& os, const Matrix& m) {
for (int i = 0; i < cols; i++)
{
for (int j = 0; j < rows; j++)
os << m.mat[i][j] << " ";
os << std::endl;
}
return os;
}
friend Matrix operator+(Matrix other, T num) {
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
other.mat[i][j] += num;
return other;
}
// No need for any special members
};

C++ OOP - Arrays (matrices) multiplication, deleting object [duplicate]

This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 7 years ago.
I am writing simple C++ application to multiply two matrices. Yes, I am aware this version doesn't check e.g. whether number of rows is greater than zero.
I can create two objects using a default constructor and I can create third object (a result of multiplication of two previous objects of the same class). I can't however correctly delete this third object. When I try, an "Access violation reading location" exception is throw. Can you tell me what am I missing? Is there something I forget to initialize? This exception is only thrown when using myThirdFunction.
Any other advice on making this code better is welcome :)
#include <iostream>
#include <ctime>
#include <iomanip>
using namespace std;
class MyArray
{
int Variable1 = 0;
int Variable2 = 0;
float ** myArray;
public:
MyArray() : Variable1(0), Variable2(0){ myFunction(); }
MyArray (int variable1, int variable2) : Variable1(variable1):
Variable2(variable2){ myFunction(); }
MyArray(const MyArray &myArrayA, const MyArray &myArrayB) :
Variable1(myArrayA.Variable1), Variable2(myArrayB.Variable2)
{ myThirdFunction(myArrayA, myArrayB); }
MyArray(const MyArray &myArray)
{ Variable1=myArray.Variable1; Variable2 = myArray.Variable2;
this->myArray =myArray.myArray; }
void myFunction() {
cin >> Variable1;
cin >> Variable2;
myArray = new float*[Variable1];
myOtherFunction();
}
void myOtherFunction() {
for (int i = 0; i < Variable1; ++i)
{
myArray[i] = new float[Variable2];
for (int j = 0; j < Variable2; ++j)
myArray[i][j] = rand() % (10 - 0) + 0;
}
}
void myThirdFunction(MyArray myArrayA, MyArray myArrayB)
{
Variable1 = myArrayA.Variable1;
Variable2 = myArrayB.Variable2;
myArray = new float*[Variable1];
for (int i = 0; i < Variable1; ++i)
{
myArray[i] = new float[Variable2];
for (int j = 0; j < Variable2; ++j)
{
float tempVariable = 0;
for (int q = 0; q < myArrayA.Variable2; ++q)
{
tempVariable += myArrayA.myArray[i][q] * myArrayB.myArray[q][j];
}
myArray[i][j] = tempVariable;
}
}
}
void displayMyArray() {
for (int i = 0; i < Variable1; ++i)
{
for (int j = 0; j < Variable2; ++j)
cout << myArray[i][j] << '\t';
cout << endl;
}
}
~MyArray() {
for (int i = 0; i < Variable1; ++i)
{
delete[] myArray[i];
}
delete[]myArray;
}
};
int main(){
srand(time(0));
MyArray myArrayA;
myArrayA.displayMyArray();
cout << endl;
MyArray myArrayB;
myArrayB.displayMyArray();
cout << endl;
MyArray myArrayC(myArrayA, myArrayB);
myArrayC.displayMyArray();
getchar();
getchar();
return 0;
}
Thanks :)
The member myArray is a pointer, and in your copy constructor you just copy the pointer without creating a new array. Because myThirdFunction takes both arguments by value, it creates two copies of the original objects. And because the copy constructor doesn't create a new value, when those two copies go out of scope at the end of the function, the original pointers now point to deallocated memory. Whenever the original two objects are destroyed, the destructor tries to delete memory that was already deleted.
From the beginning, you have this constructor:
MyArray(const MyArray &myArrayA, const MyArray &myArrayB)
{
myThirdFunction(myArrayA, myArrayB); //This call creates two new objects
}
The signature of myThirdFunction being void myThirdFunction(MyArray myArrayA, MyArray myArrayB), you pass by value and create two new copies. That calls the copy constructors for the two parameters:
MyArray(const MyArray &myArray)
{
this->myArray =myArray.myArray; //shallow copy, very bad
}
The new objects now point to the same memory as the originals. So, when they are destroyed at the end of myThirdFunction, the original pointers become garbage. In a broad view, this happens. float* p = new float; delete p; delete p; The solution is to make the copy constructor actually copy the elements, not the pointers:
MyArray(const MyArray &p_copy) //The name confused me so I changed it
{
Variable1 = p_copy.Variable1;
Variable2 = p_copy.Variable2;
myArray new float*[Variable1];
for (int i = 0; i < Variable1; ++i)
{
myArray[i] = new float[Variable2];
for (int j = 0; j < Variable2; ++j)
myArray[i][j] = p_copy.myArray[i][j];
}
}
In addition, you probably want to pass to myThirdFunction by constant reference.
void myThirdFunction(const MyArray& myArrayA, const MyArray& myArrayB)
I don't see a need to create two temporary objects here.
At the first time this code will works.
#include <iostream>
#include <ctime>
#include <iomanip>
using namespace std;
class MyArray
{
int Variable1;
int Variable2;
float ** myArray;
public:
MyArray() : myArray(NULL), Variable1(0), Variable2(0) // initialize pointers with NULL is important
{
myFunction();
}
MyArray (int variable1, int variable2) : myArray(NULL), Variable1(variable1),
Variable2(variable2)
{
myFunction();
}
MyArray(const MyArray &myArrayA, const MyArray &myArrayB) : myArray(NULL),
Variable1(myArrayA.Variable1), Variable2(myArrayB.Variable2)
{
myThirdFunction(myArrayA, myArrayB);
}
MyArray(const MyArray &myArray)
{
Variable1=myArray.Variable1; Variable2 = myArray.Variable2;
this->myArray =myArray.myArray;
}
void myFunction()
{
cin >> Variable1;
cin >> Variable2;
myArray = new float*[Variable1];
myOtherFunction();
}
void myOtherFunction()
{
for (int i = 0; i < Variable1; ++i)
{
myArray[i] = new float[Variable2];
for (int j = 0; j < Variable2; ++j)
myArray[i][j] = rand() % (10 - 0) + 0;
}
}
void myThirdFunction(MyArray myArrayA, MyArray myArrayB)
{
// cols of first must be same as rows of second
if (myArrayA.Variable2 != myArrayB.Variable1)
return;
// memory must be cleaned before new array creation
clearArray();
Variable1 = myArrayA.Variable1;
Variable2 = myArrayB.Variable2;
myArray = new float*[Variable1];
for (int i = 0; i < Variable1; ++i)
{
myArray[i] = new float[Variable2];
for (int j = 0; j < Variable2; ++j)
{
float tempVariable = 0;
for (int q = 0; q < myArrayA.Variable2; ++q)
{
tempVariable += myArrayA.myArray[i][q] * myArrayB.myArray[q][j];
}
myArray[i][j] = tempVariable;
}
}
}
void displayMyArray()
{
for (int i = 0; i < Variable1; ++i)
{
for (int j = 0; j < Variable2; ++j)
cout << myArray[i][j] << '\t';
cout << endl;
}
}
~MyArray()
{
clearArray();
}
// clear memory and deinitialize pointers
void clearArray()
{
if (myArray == NULL)
return;
for (int i = 0; i < Variable1; ++i)
{
delete[] myArray[i];
myArray[i] = NULL;
}
delete[]myArray;
myArray = NULL;
}
};
int main(){
srand(time(0));
MyArray myArrayA;
myArrayA.displayMyArray();
cout << endl;
MyArray myArrayB;
myArrayB.displayMyArray();
cout << endl;
MyArray myArrayC(myArrayA, myArrayB);
myArrayC.displayMyArray();
getchar();
getchar();
return 0;
}
but I strongly recomend you to create proper copy constructor and assignment operator means (operator=) to proper object creation and destruction.
Here I post my own matrix realization to refer you in what way you can approve your code.
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
using namespace std::
class Matrix
{
public:
Matrix();
Matrix(int rowcount,int colcount);
Matrix(int rowcount,int colcount,float* matrix);
Matrix(const Matrix& rhs);
~Matrix();
/////////////////////////////////////////////////////////////
Matrix& operator = (const Matrix& rhs);
Matrix operator + (const Matrix& rhs);
Matrix operator - (const Matrix& rhs);
Matrix operator * (float scale);
Matrix operator * (const Matrix& rhs);
void operator += (const Matrix& rhs);
void operator -= (const Matrix& rhs);
void operator *= (float scale);
void operator *= (const Matrix& rhs);
float operator [] (int offset) const;
float& operator [] (int offset);
friend ostream& operator << (ostream& _str,const Matrix& rhs);
/////////////////////////////////////////////////////////////
void setCols(int cols);
void setRows(int rows);
void setMatrix(float* matrix);
int getCols() const
{
return itsCols;
}
int getRows() const
{
return itsRows;
}
const float* getMatrix() const
{
Invariants();
return itsMatrix;
}
void Invariants() const
{
if ((!(itsCols && itsRows && itsMatrix)) && (itsRows < 0) && (itsCols < 0))
{
cout << "Not allowed action!\n";
getch();
exit(0);
}
}
/////////////////////////////////////////////////////////////
private:
float* itsMatrix;
int itsRows;
int itsCols;
};
Matrix::Matrix()
{
itsRows = 0;
itsCols = 0;
itsMatrix = NULL;
}
Matrix::Matrix(int rowcount,int colcount)
{
itsRows = rowcount;
itsCols = colcount;
itsMatrix = new float[itsRows * itsCols];
Invariants();
}
Matrix::Matrix(int rowcount,int colcount,float* matrix)
{
itsRows = rowcount;
itsCols = colcount;
itsMatrix = new float[itsCols * itsRows];
int counter = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < itsCols; j++)
{
itsMatrix[counter] = matrix[counter];
counter++;
}
}
Invariants();
}
Matrix::Matrix(const Matrix& rhs)
{
itsCols = rhs.getCols();
itsRows = rhs.getRows();
itsMatrix = new float[itsRows * itsCols];
int counter = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < itsCols; j++)
{
itsMatrix[counter] = rhs[counter];
counter++;
}
}
}
Matrix::~Matrix()
{
itsCols = 0;
itsRows = 0;
delete [] itsMatrix;
itsMatrix = NULL;
}
Matrix& Matrix::operator = (const Matrix& rhs)
{
if (&rhs == this)
return *this;
else
{
itsRows = rhs.getRows();
itsCols = rhs.getCols();
delete [] itsMatrix;
itsMatrix = NULL;
itsMatrix = new float[itsRows * itsCols];
int counter = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < itsCols; j++)
{
itsMatrix[counter] = rhs[counter];
counter++;
}
}
return *this;
}
}
float& Matrix::operator [] (int offset)
{
Invariants();
if ((offset > -1) && (offset < itsCols * itsRows))
return itsMatrix[offset];
else
{
cout << "You cann't reach this element!\n";
getch();
exit(0);
}
return itsMatrix[offset];
}
float Matrix::operator [] (int offset) const
{
Invariants();
if ((offset > -1) && (offset < itsCols * itsRows))
return itsMatrix[offset];
else
{
cout << "You cann't reach this element!\n";
getch();
exit(0);
}
return 0;
}
Matrix Matrix::operator + (const Matrix& rhs)
{
Invariants();
if (!((this->itsCols == rhs.getCols()) &&
(this->itsRows == rhs.getRows())))
{
cout << "Cann't perform addiction of matrixes!\n";
getch();
exit(0);
}
Matrix temp(itsRows,itsCols);
int counter = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < itsCols; j++)
{
temp[counter] = itsMatrix[counter] + rhs[counter];
counter++;
}
}
return temp;
}
Matrix Matrix::operator - (const Matrix& rhs)
{
Invariants();
if (!((this->itsCols == rhs.getCols()) &&
(this->itsRows == rhs.getRows())))
{
cout << "Cann't perform substraction of matrixes!\n";
getch();
exit(0);
}
Matrix temp(itsRows,itsCols);
int counter = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < itsCols; j++)
{
temp[counter] = itsMatrix[counter] - rhs[counter];
counter++;
}
}
return temp;
}
Matrix Matrix::operator * (float scale)
{
Invariants();
Matrix temp(itsRows,itsCols);
int counter = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < itsCols; j++)
{
temp[counter] = itsMatrix[counter] * scale;
counter++;
}
}
return temp;
}
Matrix Matrix::operator * (const Matrix& rhs)
{
Invariants();
if (!(itsCols == rhs.getRows()))
{
cout << "Cann't perform multiplication of matrixes!\n";
getch();
exit(0);
}
Matrix temp(itsRows,rhs.getCols());
int counter = 0;
float sum = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < rhs.getCols(); j++)
{
for (int k = 0; k < itsCols; k++)
{
sum += itsMatrix[i * itsCols + k] *
rhs[k * rhs.getCols() + j];
}
temp[counter] = sum;
sum = 0;
counter++;
}
}
return temp;
}
void Matrix::operator += (const Matrix& rhs)
{
if (!((this->itsCols == rhs.getCols()) &&
(this->itsRows == rhs.getRows())))
{
cout << "Cann't perform addiction of matrixes!\n";
getch();
exit(0);
}
Matrix temp(itsRows,itsCols);
int counter = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < itsCols; j++)
{
temp[counter] = itsMatrix[counter] + rhs[counter];
counter++;
}
}
*this = temp;
}
void Matrix::operator -= (const Matrix& rhs)
{
if (!((this->itsCols == rhs.getCols()) &&
(this->itsRows == rhs.getRows())))
{
cout << "Cann't perform substraction of matrixes!\n";
getch();
exit(0);
}
Matrix temp(itsRows,itsCols);
int counter = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < itsCols; j++)
{
temp[counter] = itsMatrix[counter] - rhs[counter];
counter++;
}
}
*this = temp;
}
void Matrix::operator *= (float scale)
{
Invariants();
Matrix temp(itsRows,itsCols);
int counter = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < itsCols; j++)
{
temp[counter] = itsMatrix[counter] * scale;
counter++;
}
}
*this = temp;
}
void Matrix::operator *= (const Matrix& rhs)
{
Invariants();
if (!(itsCols == rhs.getRows()))
{
cout << "Cann't perform multiplication of matrixes!\n";
getch();
exit(0);
}
Matrix temp(itsRows,rhs.getCols());
int counter = 0;
float sum = 0;
for (int i = 0; i < itsRows; i++)
{
for (int j = 0; j < rhs.getCols(); j++)
{
for (int k = 0; k < itsCols; k++)
{
sum += itsMatrix[i * itsCols + k] *
rhs[k * rhs.getCols() + j];
}
temp[counter] = sum;
sum = 0;
counter++;
}
}
*this = temp;
}
ostream& operator << (ostream& _str,const Matrix& rhs)
{
rhs.Invariants();
int counter = 0;
for (int i = 0; i < rhs.getRows(); i++)
{
for (int j = 0; j < rhs.getCols(); j++)
{
_str << rhs[counter] << "\t";
counter++;
}
_str << endl;
}
return _str;
}
float arr1[] =
{
2, 2, 2,
-1, -3, -5,
16, 8, 24,
8, 0, 16
};
float arr2[] =
{
15,
2,
-4
};
int main()
{
clrscr();
Matrix m1(4,3,arr1);
Matrix m2(3,1,arr2);
cout << "Matrix 1:\n";
cout << m1 << endl;
cout << "Matrix 2:\n";
cout << m2 << endl;
cout << "Matrix 1 * Matrix 2\n";
cout << m1 * m2 << endl;
getch();
cout << "Matrix 1 + Matrix 1\n";
cout << m1 + m1 << endl;
getch();
cout << "Matrix 1 - Matrix 1\n";
cout << m1 - m1 << endl;
getch();
cout << "Matrix 1 * 4\n";
cout << m1 * 4 << endl;
getch();
return 0;
}

Matrix - reading from file

I got problem using function to read matrix from file...
my class looks like this:
#include<iostream>
#include<cmath>
#include<string>
#include<fstream>
using namespace std;
class Matrix
{
public:
Matrix(int, int);
Matrix(const Matrix& copyMatrix);
~Matrix();
Matrix(const char *sciezka);
Matrix& wypelnij(string);
friend ostream& operator<< (ostream&, Matrix&);
Matrix& operator+= (const Matrix&);
Matrix& operator-= (const Matrix&);
Matrix& operator*= (const Matrix&);
Matrix& operator= (const Matrix&);
friend Matrix operator* (const Matrix & left, const Matrix & right);
friend Matrix operator+ (const Matrix & left, const Matrix & right);
friend Matrix operator- (const Matrix & left, const Matrix & right);
class AllocError{};
class OpenError{};
class IncorrectSize{};
private:
double **macierz;
unsigned int wiersze, kolumny;
};
constructors:
Matrix::Matrix(int x = 1, int y = 1): wiersze(x), kolumny(y)
{
if (wiersze < 1 || kolumny < 1)
{
throw AllocError();
}
macierz = new double*[wiersze];
for (unsigned i = 0; i < wiersze; i++)
{
macierz[i] = new double[kolumny];
for (unsigned j = 0; j < kolumny; j++)
{
macierz[i][j] = 0;
}
}
}
Matrix::Matrix(const Matrix& copyMatrix)
{
wiersze=copyMatrix.wiersze;
kolumny=copyMatrix.kolumny;
macierz = new double*[wiersze];
for (unsigned i = 0; i < wiersze; i++)
{
macierz[i] = new double[kolumny];
for (unsigned j = 0; j < kolumny; j++)
{
macierz[i][j] = copyMatrix.macierz[i][j];
}
}
}
and finally the function
Matrix::Matrix(const char *sciezka)
{
ifstream plik(sciezka);
if (plik.good() != true)
{
throw OpenError();
}
unsigned w, k;
plik >> w >> k;
if (w < 1 || k < 1) throw AllocError();
double **temp = new double*[w];
double *pamiec = new double[w * k];
for (unsigned i = 0; i < w; i++)
{
temp[i] = pamiec + (i * k);
}
for (unsigned i = 0; i < w; i++)
{
for (unsigned j = 0; j < k; j++)
{
plik >> temp[i][j];
}
}
wiersze=w;
kolumny=k;
macierz=temp;
//for (unsigned i = 0; i < w; i++) //IT WORKS TOO
// {
// macierz[i] = temp[i];
// }
for (unsigned i = 0; i < w; i++)
{
for (unsigned j = 0; j < k; j++)
{
macierz[i][j] = temp[i][j];
}
}
plik.close();
//delete [] *temp;
//delete [] temp;
}
It works just fine when I dont use delete at the end of the funtion, when I do, some numbers are wrong. If I dont it crashes after finishing all calculations Matrix A("text.txt") Matrix B(5,5) Fill.B("B") Matrix C(5,5)
C=A+B etc...
#edit
I just made it work changing the end of the F to:
wiersze=w;
kolumny=k;
//macierz=temp;
macierz = new double*[w];
for (unsigned i = 0; i < w; i++)
{
macierz[i] = new double[k];
for (unsigned j = 0; j < k; j++)
{
macierz[i][j] = temp[i][j];
}
}
plik.close();
delete [] *temp;
delete [] temp;
}
is there any easier way to read from file? I dont really like this code
For deleting the matrix you should follow the reverse order of allocation, following should do :
for (unsigned i = 0; i < w; i++)
{
delete [] macierz[i] ;
}
delete [] macierz ;