Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Yakoot
15 / 15 / 2
Регистрация: 13.11.2011
Сообщений: 65
#1

Непонятное явление при перегрузке умножения в классе матриц - C++

19.12.2011, 15:18. Просмотров 740. Ответов 16
Метки нет (Все метки)

ну собсна есть класс
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
class matrix
{
private:
    int n, m;
    double *p;
public:
    matrix();   
    matrix(int, double [] = NULL);
    matrix(int, int, double [] = NULL);
    matrix(const matrix &);
    ~matrix();
    bool check_plus(const matrix &) const;
    bool check_mult(const matrix &) const;
    double max() const;
    double min() const;
    friend std::ostream &operator <<(std::ostream &, const matrix&);
    const double *operator [](int) const;
    double *operator [](int);
    matrix &operator =(const matrix &);
    matrix &operator +=(const matrix &);
    matrix &operator -=(const matrix &);
    matrix &operator *=(const matrix &);
    matrix &operator *=(double);
};
 
matrix operator +(const matrix &, const matrix &);
matrix operator -(const matrix &, const matrix &);
matrix operator *(const matrix &, const matrix &);
matrix operator *(const matrix &, double);
двухмерный массив хранится в виде одномерного.. все прекрасно работает.. но препод подошел, и написал для проверки умножения
C++
1
matrix z2 = 2*z;
при этом вываливается исключение, прописанное в операции *=
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 &a)
{
    if (this->check_mult(a))
    {
        double *tmp;
        tmp = new double[n*a.m];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < a.m; j++)
            {
                tmp[a.m*i+j] = 0;
                for (int k = 0; k < m; k++)
                    tmp[a.m*i+j] += p[i*n+k]*a.p[k*a.m+j];
            }
        for (int i = 0; i < n*a.m; i++)
            p[i] = tmp[i];
        m = a.m;
        return *this;
    }
    else
        throw "Error: wrong sizes";
}
умножение на скаляр у меня перегружается так

C++
1
2
3
4
5
6
matrix operator *(const matrix &a, double k)
{
    matrix tmp(a);
    tmp *= k;
    return tmp;
}
не могу понять в чем дело.. перегрузил умножение скаляра на вектор, но он сказал пока закомментить и решить проблему не создавая

Добавлено через 16 минут
.....
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.12.2011, 15:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Непонятное явление при перегрузке умножения в классе матриц (C++):

Умножение матриц при перегрузке (*) в классе - C++
В чём собственно проблема: При перегрузке умножения, в результирующей матрице выбивает мусор( если быть точным, то максимальное значение...

Ошибка при перегрузке операторов в классе - C++
Я создал класс myNVector для работы с векторами произвольного размера: в заголовочном файле: class myNVector { public: ...

Ошибка при перегрузке "operator ==" в классе - C++
Если объявляю operator== в классе, то ошибка слишком много параметров для функции оператора #include &lt;iostream&gt; class comp {...

Непонятное объявление в классе - C++
Здравствуйте! Помогите разобраться в следущем коде: typedef float (* ClassAFunc)(const float x, const float z);//откуда берется...

Непонятное поведение list, vector в другом классе - C++
Салют. class _auxObserver { --- list&lt;gmObjBase*&gt; mObservedObj; vector&lt;int&gt; b; public: ...

Подпрограмма умножения 2 матриц - C++
#include&lt;iostream.h&gt; const int N=20;const int M=25; double m,l,n; void d(double x,double y,double z) void main () { int i,j; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,368
19.12.2011, 15:39 #2
Тебе нужно еще перегрузить умножение на скаляр так:
C++
1
matrix operator *(double k, const matrix &a);
В текущей реализации все сработало бы, если бы он написал matrix z2 = z*2; ....... :-)
Yakoot
15 / 15 / 2
Регистрация: 13.11.2011
Сообщений: 65
19.12.2011, 16:42  [ТС] #3
ну это то понятно.. я ж писал что так и перегрузил второй раз, но он сказал закомментить и пока не пользоваться второй перегруженной функцией.. правда я так и не понял что ему от меня надо.. либо объяснить, почему не работает умножение при такой записи, тоесть почему оно выдает исключение из другой операции.. либо исправить чото, чтобы оно работало
Amalthea
1 / 1 / 0
Регистрация: 24.11.2012
Сообщений: 8
24.11.2012, 11:09 #4
100% лаба Романенко) скорее всего надо объяснить почему не работает.
Yakoot
15 / 15 / 2
Регистрация: 13.11.2011
Сообщений: 65
26.11.2012, 08:17  [ТС] #5
=)) она самая.. ну вроде тогда разобрался, уже и не помню, в чем проблема была)
Amalthea
1 / 1 / 0
Регистрация: 24.11.2012
Сообщений: 8
26.11.2012, 14:49 #6
а можно остальной код посмотреть? я просто как двумерный массив ее писала. почерк романенко по количеству констов можно узнать))))
Yakoot
15 / 15 / 2
Регистрация: 13.11.2011
Сообщений: 65
26.11.2012, 15:25  [ТС] #7
сейчас гляну, может осталось)

Добавлено через 3 минуты
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
//matrix.h
#pragma once
 
#include <iostream>
 
class matrix
{
private:
    int n, m;
    double *p;
public:
    matrix();   
    explicit matrix(int, double [] = NULL);
    matrix(int, int, double [] = NULL);
    matrix(const matrix &);
    ~matrix();
    bool check_plus(const matrix &) const;
    bool check_mult(const matrix &) const;
    double max() const;
    double min() const;
    friend std::ostream &operator <<(std::ostream &, const matrix&);
    const double *operator [](int) const;
    double *operator [](int);
    matrix &operator =(const matrix &);
    friend matrix &operator +=(matrix &, const matrix &);
    matrix &operator -=(const matrix &);
    matrix &operator *=(const matrix &);
    matrix &operator *=(double);
    matrix operator +(const matrix &) const;
};
 
//matrix operator +(const matrix &, const matrix &);
matrix operator -(const matrix &, const matrix &);
matrix operator *(const matrix &, const matrix &);
matrix operator *(const matrix &, double);
matrix operator *(double, const matrix &);
matrix &operator +=(matrix &, const matrix &);
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
//matrix.cpp
 
#include <stdafx.h>
#include "matrix.h"
#include <iostream>
#include <iomanip>
using namespace std;
 
matrix::matrix()
{
    p = NULL;
    n = m = 0;
    cout << "Defaul constructor " << this << endl;
}
matrix::matrix(int a, double arr[])
{
    if (a <= 0 || arr == NULL)
    {
        p = NULL;
        n = m = 0;
        cout << "Wrong arguments, defaul constructor " << this << endl;
    }
    else
    {
        n = a;
        m = a;        
        p = new double[n*m];
        for (int i = 0; i < n*n; i++)
            p[i] = arr ? arr[i] : 0.0;
        cout << "Constructor of square matrix " << n << "x" << m <<" " << this << endl;
    }
}
matrix::matrix(int a, int b, double arr[])
{
    if (a <= 0 || b <= 0 || arr == NULL)
    {
        p = NULL;
        n = m = 0;
        cout << "Wrong arguments, defaul constructor " << this << endl;
    }
    else
    {
        n = a;
        m = b;
        p = new double[n*m];
        for (int i = 0; i < n*m; i++)
            p[i] = arr != NULL ? arr[i] : 0.0;
        cout << "Constructor of rectangular matrix " << n << "x" << m <<" " << this << endl;
    }
}
matrix::matrix(const matrix &a)
{
    if (a.p != NULL)
    {
        n = a.n;
        m = a.m;
        p = new double[n*m];
        for (int i = 0; i < n*m; i++)
            p[i] = a.p[i];
    }
    else
    {
        p = NULL;
        n = m = 0;
    }
    cout << "Copy constructor " << this << endl;
}
 
matrix::~matrix()
{
    if(p != NULL) delete [] p;
    cout << "Default destructor " << this << endl;
}
bool matrix::check_plus(const matrix &a) const
{   
        return a.n == n && a.m == m;
}
bool matrix::check_mult(const matrix &a) const
{
    return a.m == n;
}
double matrix::max() const
{
    if (p != NULL)
    {
        double max = p[0];
        for (int i = 0; i < n*m; i++)
        {
            if (p[i] > max)
                max = p[i];
        }
        return max;
    }
    else
        throw "Matrix is empty";    
}
double matrix::min() const
{
    if (p != NULL)
    {
        double min = p[0];
        for (int i = 0; i < n*m; i++)
        {
            if (p[i] < min)
                min = p[i];
        }
        return min;
    }
    else
        throw "Matrix is empty";
}
std::ostream &operator <<(std::ostream& out, const matrix &c)
{
    for (int i = 0; i < c.n; i++)
    {
        for (int j = 0; j < c.m; j++) {
            out << setw(4) << c[i][j];
        }
        out << endl;
    }
    return out;
}
 
const double *matrix::operator [](int a) const
{
    if (a < 0 || a >= n)
        throw "Error: wrong string number";
    else
        return &p[a*m];
}
double *matrix::operator [](int a)
{
    if (a < 0 || a >= n)
        throw "Error: wrong string number";
    else
        return &p[a*m];
}
 
matrix &matrix::operator =(const matrix &a)
{
    if (this == &a) return *this;
    if (a.n*a.m != n*m)
    {
        if(p != NULL) delete [] p;
        p = a.m*a.n == 0 ? NULL : new double[a.m*a.n];
    }
    m = a.m;
    n = a.n;
    for (int i = 0; i < n*m; i++)
        p[i] = a.p[i];        
    return *this;
}
matrix &operator +=(matrix &a, const matrix &b)
{
    if(a.check_plus(b))
    {
        for (int i = 0; i < (a.m*a.n); i++)
                a.p[i] += b.p[i];
        return a;
    }
    else
        throw "Error: wrong sizes";
}
 
matrix &matrix::operator -=(const matrix &a)
{
    if(this->check_plus(a))
    {
        for (int i = 0; i < (m*n); i++)
            p[i] -= a.p[i];
        return *this;
    }
    else
        throw "Error: wrong sizes";
}
 
 
matrix &matrix::operator *=(const matrix &a)
{
    if (this->check_mult(a))
    {
        double *tmp;
        tmp = new double[n*a.m];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < a.m; j++)
            {
                tmp[a.m*i+j] = 0;
                for (int k = 0; k < m; k++)
                    tmp[a.m*i+j] += p[i*n+k]*a.p[k*a.m+j];
            }
        for (int i = 0; i < n*a.m; i++)
            p[i] = tmp[i];
        m = a.m;
        return *this;
    }
    else
        throw "Error: wrong sizes";
}
 
 
matrix &matrix::operator *=(double k)
{
    for (int i = 0; i < n*m; i++)
        p[i] *= k;
    return *this;
}
 
matrix matrix::operator +(const matrix &b) const
{
    matrix tmp(b);
    tmp += *this;
    return tmp;
}
matrix operator -(const matrix &a, const matrix &b)
{
    matrix tmp(a);
    tmp -= b;
    return tmp;
}
matrix operator *(const matrix &a, const matrix &b)
{
    matrix tmp(a);
    tmp *= b;
    return tmp;
}
 
matrix operator *(const matrix &a, double k)
{
    matrix tmp(a);
    tmp *= k;
    return tmp;
}
 
matrix operator *(double k, const matrix &a)
{
    matrix tmp(a);
    tmp *= k;
    return tmp;
}
Добавлено через 51 секунду
это уже с какими-то его дополнительными заданиями, не оригинал, там вон перегрузка сложения закомменчена, не помню зачем)
Amalthea
1 / 1 / 0
Регистрация: 24.11.2012
Сообщений: 8
26.11.2012, 20:02 #8
огромное спасибо. [удалено]
Amalthea
1 / 1 / 0
Регистрация: 24.11.2012
Сообщений: 8
04.12.2012, 15:44 #9
а как Вы выполняли третью лабу, там же ясно было сказано, что матрицу представить как двумерный массив, а вектор - как одномерный. Матрицу брали как основу, а вектор представляли матрицей-строкой?
Yakoot
15 / 15 / 2
Регистрация: 13.11.2011
Сообщений: 65
04.12.2012, 15:55  [ТС] #10
хм.. у нас вроде нужно было через одномерный массив делать.. или это был один из вариантов) я не помню) кажется всё-таки было несколько вариантов выполнения на выбор) я через одномерный сделал)
Amalthea
1 / 1 / 0
Регистрация: 24.11.2012
Сообщений: 8
04.12.2012, 16:03 #11
хм... интересно. а получилось так же красиво? просто вариант решения, который вы представили выше, намного короче, чем мой, сделанный через двумерный. что вызвало полный восторг)))
Yakoot
15 / 15 / 2
Регистрация: 13.11.2011
Сообщений: 65
04.12.2012, 16:17  [ТС] #12
я с двухмерным даже не представляю, как делать.. точнее, если подумать, то придумал бы, но это как-то не так.. там даже аргументы были какие-то вроде в пользу одномерного.. может быть, как раз-таки, размер кода))
Amalthea
1 / 1 / 0
Регистрация: 24.11.2012
Сообщений: 8
04.12.2012, 16:22 #13
а можешь показать? хотя бы интерфейс. я лично представляла вектор как матрицу, размером 1*n. то есть строку. ну и там куча кода, да. особенно пришлось париться с иерархией
Yakoot
15 / 15 / 2
Регистрация: 13.11.2011
Сообщений: 65
04.12.2012, 16:27  [ТС] #14
хм.. а что еще показывать, не пойму?) я вроде весь код скинул) мож у нас лабы разные?)
Amalthea
1 / 1 / 0
Регистрация: 24.11.2012
Сообщений: 8
04.12.2012, 16:29 #15
в третьей как с вектором совместил
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.12.2012, 16:29
Привет! Вот еще темы с ответами:

Скорость умножения матриц - C++
Всем привет. Решил написать 2 метода умножения матриц, и проверить скорость их выполнения. Имеем класс Mat4 в котором данные описаны...

Функция умножения матриц - C++
Так получилось , что я решила перейти в другой вуз на другую специальность. Программирование - это не мое . Но нужно сдать сессию , а на...

Написать функцию умножения матриц - C++
Условие : даны 3 матрицы . Определить функцию которая перемножит 2 матрицы. С помощью неё произвести умножение трех данных матриц. ...

Рекурсивная процедура умножения матриц - C++
Вот мне задали написать рекурсивную процедуру для умножения матриц. Я понимаю, что значит написать процедуру умножения матриц, но что...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
04.12.2012, 16:29
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru