#include <iostream>
#include <cstdlib>
#include <ctime>
#include <fstream>
using namespace std;
#include <iostream>
#include <cassert>
using namespace std;
class Matrix
{
private:
class CountingReference
{
private:
int * countingReference;
public:
int wiersz;
int kolumna;
double **wsk;
CountingReference();
CountingReference(int, int);
CountingReference(const CountingReference &);
~CountingReference();
CountingReference& operator=(CountingReference rhs);
};
CountingReference dane;
public:
friend ostream& operator<<(ostream& o, const Matrix&);
friend ostream& operator<<(const Matrix&, ostream& o);
Matrix();
Matrix(int, int);
static Matrix clone(const Matrix &);
Matrix operator+(const Matrix &) const;
Matrix operator-(const Matrix &) const;
Matrix operator*(const Matrix &) const;
Matrix operator+=(const Matrix&);
Matrix& operator-=(const Matrix&);
Matrix& operator*=(const Matrix&);
bool operator ==(const Matrix &);
friend Matrix& Random(Matrix&);
};
ostream& operator<<(ostream& o, const Matrix& Object)
{
for (int i = 0; i < Object.dane.wiersz; i++)
{
for (int j = 0; j < Object.dane.kolumna; j++)
{
o << Object.dane.wsk[i][j] << " ";
}
o << endl;
}
return o;
}
Matrix::Matrix() :
dane()
{
}
Matrix::Matrix(int wiersz, int col) :
dane(wiersz, col)
{
}
Matrix Matrix::clone(const Matrix &Object)
{
Matrix result(Object.dane.wiersz,
Object.dane.kolumna);
for (int i = 0; i < result.dane.wiersz; i++)
{
for (int j = 0; j < result.dane.kolumna; j++)
{
result.dane.wsk[i][j] = Object.dane.wsk[i][j];
}
}
return result;
}
Matrix Matrix::operator+(const Matrix &Object) const
{
return Matrix::clone(*this) +=Object;
}
Matrix Matrix::operator-(const Matrix &Object) const
{
return Matrix::clone(*this) -=Object;
}
Matrix Matrix::operator*(const Matrix &Object) const
{
return Matrix::clone(*this) *=Object;
}
Matrix Matrix::operator+=(const Matrix& Object)
{
if (dane.wiersz != Object.dane.wiersz
|| dane.kolumna != Object.dane.kolumna)
{
string wyjatek = "Nie sa rowne.";
throw wyjatek;
}
else
{
for (int i = 0; i < dane.wiersz; i++)
{
for (int j = 0; j < dane.kolumna; j++)
{
dane.wsk[i][j] += Object.dane.wsk[i][j];
}
}
}
return *this;
}
Matrix& Matrix::operator-=(const Matrix& Object)
{
if (dane.wiersz != Object.dane.wiersz
|| dane.kolumna != Object.dane.kolumna)
{
string wyjatek = "Nie sa rowne.";
throw wyjatek;
}
else
{
for (int i = 0; i < dane.wiersz; i++)
{
for (int j = 0; j < dane.kolumna; j++)
{
dane.wsk[i][j] -= Object.dane.wsk[i][j];
}
}
}
return *this;
}
Matrix& Matrix::operator*=(const Matrix& Object)
{
if (dane.kolumna != Object.dane.wiersz)
{
string wyjatek = "Nie sa rowne.";
throw wyjatek;
}
else
{
int m = 0, n = 0;
double temp = 0;
m = dane.wiersz;
n = Object.dane.kolumna;
Matrix A(m, n);
for (int i = 0; i < dane.wiersz; i++)
{
for (int j = 0; j < Object.dane.kolumna; j++)
{
for (int k = 0; k < dane.kolumna; k++)
{
temp += dane.wsk[i][k] * Object.dane.wsk[k][j];
}
A.dane.wsk[i][j] = temp;
temp = 0;
}
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
dane.wsk[i][j] = A.dane.wsk[i][j];
}
}
}
return *this;
}
bool Matrix::operator ==(const Matrix& Object)
{
int i, j;
for (i = 0; i < dane.wiersz; i++)
{
for (j = 0; j < dane.kolumna; j++)
{
if (dane.wsk[i][j] != Object.dane.wsk[i][j])
{
return false;
}
}
}
return true;
}
Matrix& Random(Matrix& Object)
{
for (int i = 0; i < Object.dane.wiersz; i++)
{
for (int j = 0; j < Object.dane.kolumna; j++)
{
Object.dane.wsk[i][j] = rand() % 100 + 1;
}
}
return Object;
}
Matrix::CountingReference::CountingReference() :
countingReference(new int(1)), wiersz(0), kolumna(0), wsk(NULL)
{
}
Matrix::CountingReference::CountingReference(int wier, int kol) :
countingReference(new int(1)), wiersz(wier), kolumna(kol), wsk(new double*[wier])
{
for (int i = 0; i < wier; i++)
{
wsk[i] = new double[kol];
}
cout << countingReference << " was created \n";
}
Matrix::CountingReference::CountingReference(const CountingReference & src) :
countingReference(src.countingReference), wiersz(src.wiersz), kolumna(src.kolumna), wsk(src.wsk)
{
++(*countingReference);
cout << countingReference << " was copied (" << *countingReference << ")\n";
}
Matrix::CountingReference::~CountingReference()
{
--(*countingReference);
cout << countingReference << " was decremented (" << *countingReference << ")\n";
if (!*countingReference)
{
cout << countingReference << " was destroyed\n";
for (int i = 0; i < wiersz; i++)
{
delete[] wsk[i];
}
delete[] wsk;
delete countingReference;
}
}
Matrix::CountingReference & Matrix::CountingReference::operator=(CountingReference rhs)
{
cout << countingReference << " was replaced by " << rhs.countingReference << "\n";
swap(countingReference, rhs.countingReference);
swap(wsk, rhs.wsk);
swap(wiersz, rhs.wiersz);
swap(kolumna, rhs.kolumna);
return *this;
}
int main()
{
cout << "Create A\n";
Matrix A(3, 3);
cout << "Create B\n";
Matrix B(3, 3);
cout << "Create C\n";
Matrix C(3, 3);
cout << "Create D\n";
Matrix D(3, 3);
Matrix F(); // declares function F. See Most Vexing Parse
Random(B);
Random(C);
Random(D);
cout << "B: " << endl << B << endl;
cout << "C: " << endl << C << endl;
cout << "D: " << endl << D << endl;
cout << "A = B + C\n";
A = B + C;
cout << "A = B\n";
A = B;
cout << "B = C\n";
B = C;
cout << "C = D\n";
C = D;
cout << "A = B\n";
A = B;
cout << "B = C\n";
B = C;
cout << "A = B\n";
A = B;
cout << "Done. Cleaning up\n";
return 0;
}