Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 30.11.2016
Сообщений: 11

Класс Матрица, перегрузка арифметических операций

06.04.2017, 23:28. Показов 3321. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Не удаётся реализовать перегрузку операторов сложения, вычитания и т.д. причём не понимаю в чём именно ошибка, даже конструктор копирования отказывается работать
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#pragma once
#ifndef MATRIX_H_
#define MATRIX_H_
 
#include <fstream>
 
class Matrix {
    friend std::ostream& operator << (std::ostream&, const Matrix &);
    friend std::istream& operator >> (std::istream&, Matrix &);
    friend Matrix operator * (const Matrix&, double); //умножение матрицы на число
private:
    double **Matr;
    int str; //строки матрицы
    int col; //столбцы матрицы
 
public:
    Matrix(); //консткурктор по умолчанию
    Matrix(int, int); //конструктор инициализации объекта
    Matrix(Matrix &matrixToCopy);//констркутор копирования 
    ~Matrix(); //дестркутор
 
    Matrix operator + (const Matrix&) const; //сложение матриц
    Matrix operator -  (const Matrix&) const; //разность матриц
    Matrix operator *  (const Matrix&) const; //умножние матриц
    Matrix& operator=(const Matrix&);
    bool operator == (const Matrix&) const;
    double *operator[](int k);
};
 
#endif // !MATRIX_H_
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "Matrix.h"
#include <iostream>
 
Matrix::Matrix()
{
    str = 0;
    col = 0;
    Matr = NULL;
}
 
Matrix::Matrix(int Rows, int Colmns)
{
    str = (Rows > 0 ? Rows : 10);
    col = (Colmns > 0 ? Colmns : 10);
    Matr = new double*[str];
    for (int count = 0; count < str; count++)
        Matr[count] = new double[col];
    for (int in = 0; in < str; in++)
        for (int jn = 0; jn < col; jn++)
            std::cin>>Matr[in][jn];
}
 
 
Matrix::Matrix(Matrix &matrixToCopy)
{
    int Row = matrixToCopy.str;
    int Col = matrixToCopy.col;
    Matr = new double *[Row];
    for (int i = 0; i<Row; i++)
        Matr[i] = new double[Col];
    for (int i = 0; i < Row; i++) 
        for (int j = 0; j < Col; j++)
            Matr[i][j] = matrixToCopy.Matr[i][j];
 
}
 
Matrix::~Matrix()
{
    for (int i = 0; i < str; i++)
        delete []Matr[i];
    delete []Matr;
}
 
Matrix Matrix::operator+(const Matrix &m1) const
{
    Matrix result;
    for (int i = 0; i < m1.str; i++)
        for (int j = 0; j < m1.col; j++)
            result.Matr[i][j] = Matr[i][j] + m1.Matr[i][j];
    return result;
}
 
 
bool Matrix::operator==(const Matrix &N) const
{
    bool k = 1;
    int i, j;
    for (i = 0; i <N.str ; i++) {
        for (j = 0; j <N.col; j++) {
            if (Matr[i][j] != N.Matr[i][j]) {
                k = 0;
            }
        }
    }
    return k;
}
 
double * Matrix::operator[](int k)
{
    if (k<0 || k >= (str*col))
    {
        std::cerr << "\n Ошибка индекса: " << k << std::endl;
        exit(1); // завершить работу программы, неправильный индекс
    }
    return Matr[k];
}
 
 
 
std::ostream& operator << (std::ostream& cout, const Matrix &matrix)
{
    int row = matrix.str;
    int col = matrix.col;
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++)
            cout << matrix.Matr[i][j] << '\t';
        cout << std::endl;
    }
    return cout;
}
 
std::istream & operator >> (std::istream& cin, Matrix &matrix)
{
    int row = matrix.str;
    int col = matrix.col;
    for (int i = 0; i < row; i++)
        for (int j = 0; j < col; j++)
            cin >> matrix.Matr[i][j];
    return cin;
}
 
 
Matrix Matrix::operator-(const Matrix& m1) const
{
    Matrix razn;
    for (int i = 0; i < m1.str; i++)
        for (int j = 0; j < m1.col; j++)
            razn.Matr[i][j] = Matr[i][j]- m1.Matr[i][j];
    return razn;
}
 
Matrix Matrix::operator * (const Matrix& m3) const
{
    Matrix result;
    for (int i = 0; i < m3.str; i++)
        for (int j = 0; j < m3.col; j++)
            for (int k = 0; k <col;k++)
                result.Matr[i][j] += m3.Matr[i][k] * Matr[k][j];
    return result;
}
 
Matrix & Matrix::operator=(const Matrix &m)
{
    for (int i = 0; i < str; i++)
        delete[]Matr[i];
    delete[]Matr;
    int Row = m.str;
    int Col = m.col;
    Matr = new double *[Row];
    for (int i = 0; i<Row; i++)
        Matr[i] = new double[Col];
    for (int i = 0; i<Row; i++)
        for (int j = 0; j<Col; j++)
            Matr[i][j] = m.Matr[i][j];
    return *this;
}
 
Matrix operator*(const Matrix&ob, double d)
{
        Matrix temp;
        // заполнение матрицы-результата
        for (int i = 0; i < ob.str; i++)
            for (int j = 0; j < ob.col; j++)
                temp.Matr[i][j] = ob.Matr[i][j] * d;
        return temp;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.04.2017, 23:28
Ответы с готовыми решениями:

Класс Money, перегрузка арифметических операций для работы с денежным форматом
//Ñîçäàéòå êëàññ Money, â êîòîðîì ïåðåãðóçèòå àðèôìåòè÷åñêèå //îïåðàöèè äëÿ ðàáîòû ñ äåíåæíûì ôîðìàòîì. Ïåðåãðóçèòå äâà îïåðàòîðà ...

Перегрузка арифметических операций
Помогите пожалуйста. Создать класс типа Float. Перегрузите для него арифметические операции, операции сравнения.

Перегрузка арифметических операций
Для соответствующего класса, перегрузить арифметические операции(+,-,*,/). При перезгузке арифметические действия должны выполняться...

9
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
07.04.2017, 00:22
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Matrix Matrix::operator+(const Matrix &m1) const
{
    Matrix result;
    // куда указывает result.Matr после конструктора по умолчанию? в никуда.
    for (int i = 0; i < m1.str; i++)
        for (int j = 0; j < m1.col; j++)
            // раз result.Matr указывает в никуда, то result.Matr[i][j] = ... - это ошибка.
            result.Matr[i][j] = Matr[i][j] + m1.Matr[i][j];
    return result;
}
 
 
// Может пройдет такой вариант, а может и нет. Я долго не думал:
Matrix Matrix::operator+(const Matrix &m1) const
{
    Matrix result(m1); // размеры m1 и *this должны совпадать.
    for (int i = 0; i < m1.str; i++)
        for (int j = 0; j < m1.col; j++)
            result.Matr[i][j] += Matr[i][j];
    return result;
}
0
0 / 0 / 0
Регистрация: 30.11.2016
Сообщений: 11
07.04.2017, 08:24  [ТС]
То есть мне нужно создать еще один конструктор?
0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
07.04.2017, 08:52
Цитата Сообщение от fokinsasha2014 Посмотреть сообщение
То есть мне нужно создать еще один конструктор?
а почему не попробывать вариант который скинули выше?
0
0 / 0 / 0
Регистрация: 30.11.2016
Сообщений: 11
07.04.2017, 09:12  [ТС]
Он не работает(
0
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
07.04.2017, 10:53
надо поправить свой кривой конструктор копирования.
раз вы на это напоролись, теперь должны понимать, почему
конструктор покирования должен константную ссылку принимать,
а не неконстантную. иначе нельзя делать копии из констант:
Matrix::Matrix(const Matrix& matrixToCopy)
0
0 / 0 / 0
Регистрация: 30.11.2016
Сообщений: 11
07.04.2017, 23:21  [ТС]
Да я понял всё это, первый раз в своей жизни класс создаю. Как оказалось в конструкторе копирования нужно было произвести список инициализации до фигурных скобок.

Добавлено через 32 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#pragma once
#ifndef MATRIX_H_
#define MATRIX_H_
 
#include <fstream>
 
class Matrix {
    friend std::ostream& operator << (std::ostream&, const Matrix &);
    friend std::istream& operator >> (std::istream&, Matrix &);
    friend Matrix operator * (const Matrix&, double); //умножение матрицы на число
 
private:
    double **Matr;
    int str; //строки матрицы
    int col; //столбцы матрицы
 
public:
    Matrix(); //консткурктор по умолчанию
    Matrix(int, int); //конструктор инициализации объекта
    Matrix(const Matrix &); //констркутор копирования 
 
 
    Matrix operator + (const Matrix&) const; //сложение матриц
    Matrix operator -  (const Matrix&) const; //разность матриц
    Matrix operator *  (const Matrix&) const; //умножние матриц
    Matrix operator=(const Matrix &);
    void setMatrix();
    void getMatrix();
    bool operator == (const Matrix&) const;
    double *operator[](int k);
};
 
#endif // !MATRIX_H_

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#pragma once
#include "Matrix.h"
#include <iostream>
#include <iomanip>
 
Matrix::Matrix()
{
    str = 10;
    col = 10;
    Matr = new double*[str];
    for (int count = 0; count < str; count++)
        Matr[count] = new double[col];
    for (int in = 0; in < str; in++)
        for (int jn = 0; jn < col; jn++)
            Matr[in][jn] = 0;
 
}
 
Matrix::Matrix(int Rows, int Colmns)
{
    str = (Rows > 0 ? Rows : 10);
    col = (Colmns > 0 ? Colmns : 10);
    Matr = new double*[str];
    for (int count = 0; count < str; count++)
        Matr[count] = new double[col];
    for (int in = 0; in < str; in++)
        for (int jn = 0; jn < col; jn++)
            Matr[in][jn] = 0;
}
 
Matrix::Matrix(const Matrix &m)
    : Matr(new double *[m.str]), str(m.str), col(m.col)
{
    for (int i = 0; i<str; i++)
        Matr[i] = new double[col];
    for (int i = 0; i < str; i++)
        for (int j = 0; j <col; j++)
            Matr[i][j] = m.Matr[i][j];
}
 
 
bool Matrix::operator==(const Matrix &N) const
{
    bool k = 1;
    int i, j;
    for (i = 0; i <N.str; i++) {
        for (j = 0; j <N.col; j++) {
            if (Matr[i][j] != N.Matr[i][j]) {
                k = 0;
            }
        }
    }
    return k;
}
 
double * Matrix::operator[](int k)
{
    if (k<0 || k >= (str*col))
    {
        std::cerr << "\n Ошибка индекса: " << k << std::endl;
        exit(1); // завершить работу программы, неправильный индекс
    }
    return Matr[k];
}
 
 
 
std::ostream& operator << (std::ostream& cout, const Matrix &matrix)
{
    int row = matrix.str;
    int col = matrix.col;
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++)
            cout << matrix.Matr[i][j] << '\t';
        cout << std::endl;
    }
    return cout;
}
 
std::istream & operator >> (std::istream& cin, Matrix &matrix)
{
    int row = matrix.str;
    int col = matrix.col;
    for (int i = 0; i < row; i++)
        for (int j = 0; j < col; j++)
            cin >> matrix.Matr[i][j];
    return cin;
}
 
Matrix Matrix::operator+(const Matrix &m1) const
{
    Matrix result(m1.str, m1.col);
    for (int i = 0; i < m1.str; i++)
        for (int j = 0; j < m1.col; j++)
            result.Matr[i][j] = Matr[i][j] + m1.Matr[i][j];
    return result;
}
 
Matrix Matrix::operator-(const Matrix& m1) const
{
    Matrix result(m1.str, m1.col);
    for (int i = 0; i < m1.str; i++)
        for (int j = 0; j < m1.col; j++)
            result.Matr[i][j] = Matr[i][j] - m1.Matr[i][j];
    return result;
}
 
Matrix Matrix::operator * (const Matrix& m3) const
{
    Matrix result(m3.str, m3.col);
    for (int i = 0; i < m3.str; i++)
        for (int j = 0; j < m3.col; j++)
            for (int k = 0; k < str; k++)
                result[i][j] += Matr[i][k] * m3.Matr[k][j];
    return result;
}
 
Matrix Matrix::operator=(const Matrix & ob)
{
    for (int i = 0; i < str; i++) {
        for (int j = 0; j < col; j++) {
            Matr[i][j] = ob.Matr[i][j];
        }
    }
    return *this;
}
 
Matrix operator*(const Matrix&ob, double d)
{
    Matrix result(ob.str, ob.col);
    // заполнение матрицы-результата
    for (int i = 0; i < ob.str; i++)
        for (int j = 0; j < ob.col; j++)
            result.Matr[i][j] = ob.Matr[i][j] * d;
    return result;
}
 
void Matrix::setMatrix()
{
    std::cout << "Введите матрицу: " << std::endl;
    for (int ix = 0; ix < str; ix++)
        for (int jx = 0; jx < col; jx++)
            std::cin >> Matr[ix][jx];
}
 
void Matrix::getMatrix()
{
    for (int ix = 0; ix < str; ix++)
    {
        for (int jx = 0; jx < col; jx++)
            std::cout << std::setw(5) << Matr[ix][jx]; // вывод элементов матрицы на экран
        std::cout << std::endl;
    }
 
    std::cout << std::endl; // новая строка
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "Matrix.h"
#include <iostream>
 
using namespace std;
 
int main() {
    setlocale(LC_ALL, "Rus");
    int n = 0;
    int k = 0;
    cout << "Введите размерность матрицы: " << endl;
    cin >> n >> k;
    cout << "Введите матрицу (1): " << endl;
    Matrix myMatrix1(n, k);
    cout << "Вывод матрицы инициализированной конструктором: " <<'\n'<< myMatrix1 << endl;
    myMatrix1.setMatrix();
    cout << myMatrix1 << endl;
    Matrix m2(myMatrix1);
    cout << "Матрица (2), полученная с помощью конструктора копирования: " << '\n' << m2 << endl;
    if (m2 == myMatrix1)
        cout << "Операция сравнения перегружена успешно!" << endl;
    cout << "Сумма матриц (1) и (2)" << '\n' << m2 + myMatrix1 << endl;
    cout << "Разность матриц (1) и (2)" << '\n' << m2 - myMatrix1 << endl;
    Matrix m3(n, k);
    m3.setMatrix();
    cout << "Умножение матриц (1) и (3)" << '\n' << myMatrix1*m3 << endl;
    m2 = myMatrix1*m3;
    cout << "Присвоили m2 значение произведения: " << '\n' << m2 << endl;
    Matrix m4(n, k);
    m4 = m3 * 5;
    cout<< "Произведение матрицы на число: " << '\n';
    m4.getMatrix();
    system("pause");
    return 0;
}
Работающий класс матриц, всем спасибо за советы. Осталось только реализовать нахождение определителя, но это я уже сам.
0
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
08.04.2017, 19:02
мда. т.е. вызов оператора + заставит юзера сперва вводить значения с клавиатуры, а потом они перезапишутся. ну "очень удобно и логично"
0
 Аватар для GoldenId
142 / 143 / 64
Регистрация: 11.11.2010
Сообщений: 877
Записей в блоге: 10
08.04.2017, 19:43
Цитата Сообщение от fokinsasha2014 Посмотреть сообщение
C++
1
2
Matrix::Matrix(const Matrix &m)
    : Matr(new double *[m.str]), str(m.str), col(m.col)
Создаётся впечатление, что Matr - это базовый класс. Члены именуются, начиная с маленькой буквы или с подчёркивания или с m_:
C++
1
2
3
4
private:
    double **_matr;
    int _rowNum; // количество строк матрицы
    int _colNum; // количество столбцов матрицы
Так Вы их с параметрами и локальными переменными методов не спутаете.

Кроме того выделять память в списке инициализации:
C++
1
Matr(new double *[m.str])
... не скажу полностью ответственно, но выглядит сомнительно. Я бы сделал так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Matrix 
{
    // ...
protected:
    double **_data;
    int _rowNum; // или _rows или _m
    int _colNum; //или _cols или _n
    
    typedef const char * ExceptionType;
 
    // ...
protected:
    ExceptionType _allocateException = "Unable to allocate memory for array";
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Matrix::Matrix(const Matrix &other)
    : _rowNum(other._rowNum), _colNum(other._colNum)
{
    _data = new double *[other._rowNum];
    if( _data == nullptr )
        throw _allocateException;
    for (int i = 0; i<_rowNum; i++)
    {
        _data[i] = new double[_colNum];
        if( _data[i] == 0 )
            throw _allocateException;
    }
    for (int i = 0; i < _rowNum; i++)
        for (int j = 0; j <_colNum; j++)
            _data[i][j] = other.Matr[i][j];
}
Сами с обработкой исключений справитесь?

Добавлено через 7 минут
Цитата Сообщение от DU3 Посмотреть сообщение
мда. т.е. вызов оператора + заставит юзера сперва вводить значения с клавиатуры, а потом они перезапишутся. ну "очень удобно и логично"
У Вас, fokinsasha2014, действительно происходит дублирование функциональности. В:
C++
1
Matrix myMatrix1(n, k); // строка 13
и в:
C++
1
    myMatrix1.setMatrix(); // строка 15
матрица зачитывается с клавиатуры. Вы уверены, что Вам именно так и нужно?
0
0 / 0 / 0
Регистрация: 30.11.2016
Сообщений: 11
09.04.2017, 09:35  [ТС]
Я просто подумал, что так будет проще рекурсивную формулу сделать для нахождения определителя

Добавлено через 2 минуты
А насчёт списка инициализации, у меня каждый раз матрица удалялась и данные стирались и я тогда впервые столкнулся с термином список инициализации и википедии было показано так
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.04.2017, 09:35
Помогаю со студенческими работами здесь

Перегрузка арифметических операций для работы с объектами классов.
Создать класс Animal, содержащий следующие элементы: - поле «вес» float Mass; - поле «пол» char* Sex; - поле «окрас» char* Color; ...

Класс длинная арифметика с поддержкой арифметических операций
Кто-нибудь уже писал класс для работы с очень большими числами, с поддержкой операторов +-/*, если да, то дайте, пожалуйста, ссылку на код....

Класс арифметических операций матрицы как на другую матрицу так и на число
Описать класс,реализующий тип данных &quot;вещественная матрица&quot; и работу с ними.Класс должен реализовывать слудующие операции над матрицами: ...

Матрица 2x2 целых чисел(перегрузка операций)
Данные класса: статический массив элементов матрицы. Операции: сложение и умножение матриц, умножение матрицы на число, вычисление...

Класс - сортировка - перегрузка операций
Доброго времени суток! Прошу помочь или натолкнуть на путь, который решит мою маленькую задачку. Программу запилил через конструкторы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru