#include <iostream>
using namespace std;
// 1) Інкапсуляція: поля були `protected`, що погано — їх треба зробити `private` і доступ надавати через методи.
// 2) Конструктор без параметрів — створює матрицю 1x1.
// 3) Деструктор реалізований.
// 4) Перевантаження +
// 5) Перевантаження -
// 6) Обробка негативної розмірності
// 7) Перевантаження *
// 9) Клас SquareMatrix з методом trace()
using namespace std;
// 1) що негаразд із кодом з погляду інкапсуляції? Як виправити?
// 2) додайте можливість виклику конструктора без параметрів, щоб створювалася матриця розміру 1Х1
//3) реалізувати деструктор
// 4) перевантажити операцію + додавання 2х матриць
// 5) перевантажити операцію - віднімання 2х матриць
// 6) обробити створення матриці з негативною розмірністю
// 7)перевантажити операцію * множення матриці на матрицю
// 9) написати клас спадкоємець квадратна матриця, з методом обчислює слід матриці (сума елементів головної діаганалі)
template <typename T>
class Matrix
{
protected:
T **a;
int size1;
int size2;
public:
Matrix(int n, int m){
while(m<=0 and n<=0){
cout<<"Enter a different size";
cin>>n>>m;
}
size1=n;
size2=m;
a = new T * [n];
for (int i = 0; i < n; i++){
a[i] = new T [m];
}
}
T* operator [](const int i) {return a[i];}
Matrix operator+(const Matrix& lhs)const{
Matrix c(size1,size2);
for(int i=0;i<size1;i++){
for(int j=0;j<size2;j++){
c.a[i][j]=a[i][j]+lhs.a[i][j];
}
}
return c;
}
Matrix operator-(const Matrix& lhs)const{
Matrix c(size1, size2);
for(int i=0; i<size1; i++){
for(int j=0; j<size2; j++){
c[i][j]=a[i][j]-lhs.a[i][j];
}
}
return c;
}
Matrix operator*(const Matrix& lhs){
Matrix c(size1, size2);
for(int i=0; i<size1; i++){
for(int j=0; j<size2; j++){
c[i][j]=a[i][j]*lhs.a[i][j];
}
}
return c;
}
friend ostream& operator<< (ostream& os, const Matrix& a) {
// countT++;
for(int i=0;i<a.size1;i++){
for(int j=0;j<a.size2;j++){
os<<a.a[i][j]<<" ";
}
os<<endl;
}
return os;
}
friend istream& operator>> (istream& is, const Matrix& a) {
// countT++;
for(int i=0;i<a.size1;i++){
for(int j=0;j<a.size2;j++){
is>>a.a[i][j];
}
}
return is;
}
~Matrix(){
for(int i=0; i<size1; i++){
delete[] a[i];
}
delete[] a;
cout<<"dest";
}
};
template <typename T>
class SquareMatrix: public Matrix<T>{
public:
SquareMatrix(int size): Matrix<T>(size, size){
}
T trace(){
T sum=0;
for(int i=0; i<this->size1; i++){
sum+=this->a[i][i];
}
return sum;
}
};
template <typename T>
class SquareM: public Matrix<T> {
public:
SquareM(int size) : Matrix<T>(size, size) {}
T trace() {
T sum = 0;
for (int i = 0; i < this->size1; i++)
sum += this->a[i][i];
return sum;
}
};
int main(void)
{
Matrix<double> a(2, 2);
Matrix<double> b(2, 2);
cout << "Enter matrix A (2x2):\n";
cin >> a;
cout << "Enter matrix B (2x2):\n";
cin >> b;
Matrix<double> c = a + b;
cout << "\nMatrix A + B:\n" << c;
return 0;
}