Тема: ООП. Класи та операції з ними

Добрий вечір. Я написала програму на с++ для завдання і все наче б нормально, помилки не висвічуються, я запускаю, вводжу дані, після введених останніх даних вибиває помилка і до того ж в одному місці виводяться не значення а сміття.

Ось моє завдання, нижче наведу код:

Створити клас – квадратна матриця. У закритій частині описати поля: розмір матриці та двовимірний масив для зберігання її елементів (цілих чисел). Визначити конструктор та деструктор, функції для введення та виведення значень елементів матриці, обчислення сліду матриці (суми елементів головної діагоналі), сум елементів вище та нижче головної діагоналі.                                                                                                                                                                      Перевантажити операції > (порівняння матриць за слідом), + (додавання матриць), відсортувати масив екземплярів класу матриць за зростанням сліду з використанням алгоритму сортування вставками, обчислити суму двох заданих матриць з масиву (якщо це можливо). Використати оператори: new та delete.

Код:

#include <iostream>
#include <cmath>

using namespace std;

class Matrix
{
private:
    int matr[15][15];
    int Rank;
public:

    int sum;
    Matrix() {
        cout << "\nСonstructor was called for " << this << endl;
    }

    // Конструктор глибокого копіювання, а також тут ж виділяю пам'ять для свого динамічного масиву

    Matrix(const Matrix& source) {

        Rank = source.Rank;

        if (source.matr)
        {
            int** matr = new int* [Rank];
            for (int i = 0; i < Rank; i++)
                matr[i] = new int[Rank];

            for (int i = 0; i < Rank; ++i) {
                for (int j = 0; j < Rank; j++) {
                    matr[i][j] = source.matr[i][j];
                }
            }
        }
        else
            int** matr = nullptr;
    }

    ~Matrix() {
        if (matr != NULL) {
            for (int i = 0; i < Rank; ++i) {
                delete[] matr[i];
            }
            delete[] matr;
        }
        cout << "\nDestructor was called for " << this << endl;
    }

    void setMatrix() {
        cout << "\nInput rang of matrix (max 15):" << endl;
        cin >> Rank;
        if (Rank > 15) {
            while (Rank > 15) {
                cout << "Incorrect rang" << endl;
                cout << "Input rang of matrix (max 15):" << endl;
                cin >> Rank;
            }
        }
        cout << "Input elements of matrix:" << endl;
        for (int i = 0; i < Rank; i++) {
            for (int j = 0; j < Rank; j++) {
                cin >> matr[i][j];
            }
        }
        cout << endl;
    }

    void Data() {
        setMatrix();
        cout << "Elements:" << endl;
        printMatrix();
        cout << "\nSum of diagonal: " << mainDiagonal() << endl;
        cout << "Sum of elements above diagonal:  " << upSum() << endl;
        cout << "Sum of elements under diagonal: " << downSum() << endl;
    }

    void printMatrix() {
        for (int i = 0; i < Rank; i++) {
            for (int j = 0; j < Rank; j++) {
                cout << matr[i][j] << "  ";
            }
            cout << endl;
        }
    }

    int mainDiagonal() {
        sum = 0;
        for (int i = 0, j = 0; i < Rank && j < Rank; i++, j++) {
            sum = sum + matr[i][j];
        }
        return sum;
    }

    int upSum() {
        int upsum = 0;
        for (int i = 0; i < Rank - 1; i++) {
            for (int j = i + 1; j < Rank; j++) {
                upsum = upsum + matr[i][j];
            }
        }
        return upsum;
    }

    int downSum() {
        int downsum = 0;
        for (int i = 1; i < Rank; i++) {
            for (int j = 0; j < i; j++) {
                downsum = downsum + matr[i][j];
            }
        }
        return downsum;
    }

    bool Check(const Matrix& b) {

        if (this->Rank != b.Rank) {
            cout << "\nSum of these matrix is impossible!" << endl;
        }
        else {
            return true;
        }
    }

    bool operator> (const Matrix& a)
    {
        return this->sum > a.sum;

    }

    void operator+(const Matrix& b) {

        Matrix result;
        result.Rank = b.Rank;
        for (int i = 0; i < this->Rank; i++) {
            for (int j = 0; j < this->Rank; j++) {
                result.matr[i][j] = this->matr[i][j] + b.matr[i][j];
            }
        }
        cout << "\n\n Sum of two matrix = " << endl;
        result.printMatrix();
    }

};
int main() {
    system("chcp 1251");

    Matrix Matrix1;
    Matrix1.Data();
    Matrix Matrix2;
    Matrix2.Data();
    Matrix Matrix3;
    Matrix3.Data();
    Matrix Matrix4;
    Matrix4.Data();

    Matrix mass[4];
    mass[0] = Matrix1;
    mass[1] = Matrix2;
    mass[2] = Matrix3;
    mass[3] = Matrix4;

    Matrix temp;
    for (int j = 0; j < 3; j++) {
        if (mass[j] > mass[j + 1]) {
            temp = mass[j + 1];
            int t = j;
            while (mass[t] > temp) {
                mass[t + 1] = mass[t];
                if (t == 0) {
                    t--;
                    break;
                }
                t--;
            }
            mass[t + 1] = temp;
        }
    }

    cout << "\n\nArr of objects of class Matrix(slid):" << endl;
    for (int n = 0; n < 4; n++) {
        cout << mass[n].sum << endl;
    }

    if (mass[0].Check(mass[1])) {
        mass[0] + mass[1];
    }

    return 0;
}

Ця тема для мене нова, тому можуть бути якісь прості помилки, тому прошу вашої допомоги, якщо можна з наочним кодом)

Ось така вибиває помилка: Debug Assertion failed!

Підозрюю що діло в операторі new або delete, бо якщо без них і конструктора копіювання, то програма працює.

2

Re: ООП. Класи та операції з ними

lesivsolomiya, ...
Я навіть не знаю з чого тут можна почати, щоб вам допомогти..
Думаю, вам би книжку спочатку почитати, а потім писати код.

Подякували: leofun011

3

Re: ООП. Класи та операції з ними

Не розумію, а що не так?

4

Re: ООП. Класи та операції з ними

int matr[15][15];
int** matr = new int* [Rank];

Якось визначайтеся, вам який.

5

Re: ООП. Класи та операції з ними

Я пробувала одразу оголошувати як

 int **matr 

, але тоді проблеми з вводом елементів, вони не вводяться і програма одразу завершується, то залишила як статичний масив поки, бо так вводилось

6

Re: ООП. Класи та операції з ними

#include <iostream>
#include <cstdlib>
using namespace std;
class Matrix{
    int Rank;
    int** matr;
    public:
    int sum;
    Matrix(){
        cout << "\nСonstructor was called" << endl;
    }
    Matrix(Matrix& matrix){
        Rank = matrix.Rank;
        matr = new int* [Rank];
        for(int i = 0; i < Rank; ++i){
            matr[i] = new int[Rank];
            for(int j = 0; j < Rank; ++j){
                matr[i][j] = matrix.matr[i][j];
            }
        }
    }
    ~Matrix(){}
    void FreeMemory(){
        for(int i = 0; i < Rank; ++i)
        delete[] matr[i];
        delete[] matr;
    }
    void SetMatrix(){
        cout << "\nInput rang of matrix (max 15):" << endl;
        cin >> Rank;
        while(Rank > 15 || Rank < 0){
            cout << "Incorrect rang" << endl;
            cout << "Input rang of matrix (max 15):" << endl;
            cin >> Rank;
        }
        matr = new int* [Rank];
        cout << "Input elements of matrix:" << endl;
        for(int i = 0; i < Rank; ++i){
            matr[i] = new int[Rank];
            for(int j = 0; j < Rank; ++j){
                cin >> matr[i][j];
            }
        }
    }
    void PrintMatrix() {
        for (int i = 0; i < Rank; i++) {
            for (int j = 0; j < Rank; j++) {
                cout << matr[i][j] << " ";
            }
            cout << endl;
        }
    }
    int MainDiagonal() {
        sum = 0;
        for (int i = 0, j = 0; i < Rank; i++, j++) {
            sum = sum + matr[i][j];
        }
        return sum;
    }
    int UpSum() {
        int upsum = 0;
        for (int i = 0; i < Rank - 1; i++) {
            for (int j = i + 1; j < Rank; j++) {
                upsum = upsum + matr[i][j];
            }
        }
        return upsum;
    }

    int DownSum() {
        int downsum = 0;
        for (int i = 1; i < Rank; i++) {
            for (int j = 0; j < i; j++) {
                downsum = downsum + matr[i][j];
            }
        }
        return downsum;
    }
    void Data() {
        Matrix::SetMatrix();
        cout << "Elements:" << endl;
        Matrix::PrintMatrix();
        cout << "\nSum of diagonal: " << Matrix::MainDiagonal() << endl;
        cout << "Sum of elements above diagonal:  " << Matrix::UpSum() << endl;
        cout << "Sum of elements under diagonal: " << Matrix::DownSum() << endl;
    }
    bool Check(Matrix& b) {

        if (Rank != b.Rank) {
            cout << "\nSum of these matrix is impossible!" << endl;
            return false;
        }
        else {
            return true;
        }
    }
    bool operator> (Matrix& a)
    {
        return sum > a.sum;
    }
    void operator+(Matrix& b) {
        Matrix result(b);
        for (int i = 0; i < Rank; i++) {
            for (int j = 0; j < Rank; j++) {
                result.matr[i][j] += matr[i][j];
            }
        }
        cout << "\n\n Sum of two matrix: " << endl;
        result.PrintMatrix();
    }
};
void Sort(Matrix* mass, int length){
    Matrix a; 
    for(int i = 0; i < length - 1; ++i){
        for(int j = i + 1; j < length; ++j){
            if(mass[i].sum > mass[j].sum){
                a = mass[i];
                mass[i] = mass[j];
                mass[j] = a;
            }
        }
    }
    cout << "\n\nArr of objects of class Matrix(slid): ";
    for(int i = 0; i < length; ++i){
        cout << mass[i].sum << " ";
    }
    cout << endl;
}
int main() {
    int length = 2;
    Matrix* mass = new Matrix[length];
    for(int i = 0; i < length; ++i)
    mass[i].Data();
    Sort(mass, length);
    if(mass[0].Check(mass[1])){
        mass[0] + mass[1];
    }
    if(mass[0] > mass[1]){
        cout << "1 matrix sum > 2 matrix sum";
    }
    else{
        cout << "2 matrix sum <= 1 matrix sum";
    }
    for(int i = 0; i < length; ++i){
        mass[i].FreeMemory();
    }
    return 0;
}
Подякували: lesivsolomiya, leofun012

7

Re: ООП. Класи та операції з ними

Щиро дякую вам! Зараз сяду і розберу, що робила не так :)
Як добре, що є ще такі люди, як ви, що допоможуть розібратись!

8

Re: ООП. Класи та операції з ними

Вам не допомогли розібратись, а зробили за вас - це різні речі. Я все ж радив би вам почитати книжку Страуструпа або хоча б того ж Ліппмана, а особливо розділи про вказівники, класи та динамічні масиви.

Проте, можу дати вам деякі поради, як, наприклад не використовувати масив масивів. int** - необхідний лише тоді, коли у вас є рядки змінної довжини + такий метод занадто неефективний з точки зору використання/розподілу пам’яті, якщо вам потрібен квадратний/прямокутний масив, замість int** краще звернутися до математики. Див. метод at():

class Matrix {
public:
    Matrix(int const n, int const m)
        : data_{nullptr}, n_{n}, m_{m}
    {
        data_ = new int[n * m]{};
    }

    // потрібно добавити ще деструктор і видалити пам'ять
    
    int& at(int const i, int const j) { return data_[i + j * rows()]; }
    // добавте ще цей же метод тільки константний
    
    int rows   () const { return n_; }
    int columns() const { return m_; }
    
private:
    int* data_;
    int  n_;
    int  m_;
};

І розділяйте методи, наприклад функціям SetMatrix() чи PrintMatrix() - нічого робити всередині класу. Краще їх зробити вільними функціями:

void fill(Matrix& mtx) {
    int value = 0;
    for (int i = 0; i < mtx.rows(); i++) {
        for (int j = 0; j < mtx.columns(); j++) {
            std::cin >> value;
            mtx.at(i, j) = value;
        }
    }
}

void print(Matrix& mtx) {
    for (int i = 0; i < mtx.rows(); i++) {
        for (int j = 0; j < mtx.columns(); j++) {
            std::cout << mtx.at(i, j) << " ";
        }
        std::cout << std::endl;
    }
}

Ну і приклад використання:

int main()
{
    Matrix mtx(2, 3);
    fill(mtx);
    print(mtx);
}

Вивід >
5 2 1 
6 8 9 

Весь код тут.

Подякували: leofun011