Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Grinning liar!
3 / 3 / 0
Регистрация: 01.11.2012
Сообщений: 38
#1

Перегрузка оператора * - C++

27.12.2012, 00:32. Просмотров 806. Ответов 10
Метки нет (Все метки)

Здрасте.
Есть задача: Реализовать класс Matrix размерностью NxN, в которой хранятся числа типа float. Память под элементы выделять динамически. Перегрузить операции *, =. В функции main привести примеры реализации класса 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
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <conio.h>
 
using namespace std;
 
class Matrix{ 
public:
 
    int size;
 
    float **mas;
    float** create_mas (int);                   //метод создания матрицы
//  void delete_mem ();                         //очистка выделенной памяти
    Matrix const operator* (float x) const;     //перегрузка оператора
};
 
    
void main ()
{
    setlocale (LC_ALL, "Russian");          //подключение локального стандарта
    
//  const float x = 5;                      //тупо число, на которое хотелось бы умножить
    Matrix m1;                              //объявление объекта m1 класса Matrix
    int N;                                  //размер матрицы
 
    cout << "Введите размерность квадратной матрицы" << endl;
    cin >> N;
    
    m1.size = N;
    m1.create_mas(N);                   //создание матрицы и ее вывод на экран
 
    _getch();
 
}
 
 
float** Matrix::create_mas (int size){
 
    float **mas = new float *[size];        //выделяем память на массив указателей начал строк массива
 
    for (int i = 0; i < size; i++)          //выделение памяти на каждую строку массива
        {
            mas[i] = new float [size];
        }
 
        for (int i = 0; i < size; i++)      //заполняем массив числами
            for (int j = 0; j < size; j++)
                cin >> mas[i][j];
 
        for (int i = 0; i < size; i++)      //выводим первоначальный массив на экран
        {
                for (int j = 0; j < size; j++)
                    cout << setw(4) << mas[i][j] << " ";
                cout << endl;
        }
 
        return mas;
}
 
[I]Matrix const Matrix::operator* (float x) const {
 
    for (int i = 0; i < size; i++)      //заполняем массив числами
        for (int j = 0; j < size; j++)
                mas[i][j] = mas[i][j]*5;
    [B]return ;[/B]
 
}[/I]
Вопрос такого рода: при перегрузке оператора, мы, очевидно, должны вернуть объект класса Matrix (эт вроде как по заданию) Что тогда следует возвращать в функции перегрузки?

Добавлено через 2 часа 11 минут
Ой, ошибся форумом. Администратор, перенесите пожалуйста в раздел С++
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.12.2012, 00:32
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Перегрузка оператора * (C++):

Перегрузка оператора ==
Я уже встречала подобный вопрос на этом форуме, но у меня всё равно что-то не...

Перегрузка оператора ^
Здравствуйте! Необходимо перегрузить бинарный оператор ^ для транспонирования...

Перегрузка оператора +
Написал для перегрузки оператора + class BoolMatrix { private: int feet; ...

Перегрузка оператора >
Добрый день! #include &lt;stdio.h&gt; #include &lt;tchar.h&gt; #include &lt;iostream&gt; ...

Перегрузка оператора
Не могу разобратся с перегрузками, помогите пожалуйста ребята Дать определение...

Перегрузка оператора []
Всем привет! Как можно перегрузить оператор так, чтобы к нему можно было...

10
Schizorb
510 / 462 / 82
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
Завершенные тесты: 1
27.12.2012, 07:32 #2
Цитата Сообщение от Grinning liar Посмотреть сообщение
Что тогда следует возвращать в функции перегрузки?
Если тебе нужно изменить исходную матрицу, то можно вернуть *this. Только тогда логичнее заменить оператор * на *=.

C++
1
2
3
4
5
6
7
Matrix const Matrix::operator*= (float x) {
 
    for (int i = 0; i < size; i++)      
        for (int j = 0; j < size; j++)
                mas[i][j] = mas[i][j]*x;
    return *this;
}
После этого можно делать такой вызов: m1 *= 6; - элементы матрицы умножатся на 6.

Если нужно именно умножение, возвращающее результат, и не изменяющее исходный объект, то создай в функции новый объект и возвращай его.

C++
1
2
3
4
5
6
7
8
9
10
Matrix const Matrix::operator* (float x) const {
 
    Matrix res;
    res.size = size;
  
    for (int i = 0; i < size; i++)      
        for (int j = 0; j < size; j++)
                res.mas[i][j] = mas[i][j]*x;
    return res;
}
После этого можно вызывать: m2 = m1 * 6;

Только сделай нормальный конструктор, в котором будет выделяться память, и отдельно методы для ввода-вывода, а не группируй все в один метод create_mas.

Добавлено через 2 минуты
Цитата Сообщение от Grinning liar Посмотреть сообщение
float **mas = new float *[size];
Тут еще ошибка, создается локальная переменная mas, которая имеет просто одинаковое имя с элементом класса. Нужно:
C++
1
mas = new float *[size];
1
Grinning liar!
3 / 3 / 0
Регистрация: 01.11.2012
Сообщений: 38
27.12.2012, 21:26  [ТС] #3
Благодарю, вроде заработало... Однако это я себе немного упростил условия там по заданию надо перегрузить еще =, и операции ввода-вывода. Как вообще это понять, не подскажете? У меня ведь и так по заданию выполняется
Matrix2=Matrix1*number.
Каким смыслом надо наделить это равно?

Полный текст задачи звучит так:
Реализовать класс Матрикс размерностью NxN, в котором хранятся числа float. Память под элементы выделять динамически. Перегрузить *, /, =. Перегрузить операции ввода-вывода в поток. В main'e привести примеры реализации класса Матрикс.
0
Schizorb
510 / 462 / 82
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
Завершенные тесты: 1
27.12.2012, 21:33 #4
У вас память под матрицу выделяется динамически, поэтому оператор = по умолчанию не подойдет. Он сделает только поверхностное копирование. То есть для элемента float **mas; - будет скопирован адрес, хранящийся в этом указателе. В итоге в обоих объектах будет указатель на одну и ту же область памяти.

Чтобы этого не произошло, переопределите свой оператор, где полностью скопируйте матрицу вручную.
0
Grinning liar!
3 / 3 / 0
Регистрация: 01.11.2012
Сообщений: 38
27.12.2012, 23:54  [ТС] #5
Т.е. получается, что на данный момент, несмотря на то, что элементы умножаемой матрицы и конечной разные (и соответственно находятся в разных местах памяти), оба указателя хранят адрес начала исходной матрицы?
0
Grinning liar!
3 / 3 / 0
Регистрация: 01.11.2012
Сообщений: 38
30.12.2012, 00:13  [ТС] #6
Цитата Сообщение от Schizorb Посмотреть сообщение

Чтобы этого не произошло, переопределите свой оператор, где полностью скопируйте матрицу вручную.
Т.е. копировать нужно только элементы матрицы без самого указателя, да?
Так будет правильно?

C++
1
2
3
4
5
6
7
8
Matrix &Matrix::operator= (const Matrix &m2){
    
    for (int i = 0; i < size; i++)      //заполняем массив числами
        for (int j = 0; j < size; j++)
            mas[i][j] = m2.mas[i][j];
    return *this;
 
}
0
Schizorb
510 / 462 / 82
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
Завершенные тесты: 1
30.12.2012, 07:58 #7
Цитата Сообщение от Grinning liar Посмотреть сообщение
Т.е. копировать нужно только элементы матрицы
Да, так. Только тут нужно будет следить, чтобы размеры обоих матриц совпадали. Иначе, если при
C++
1
m1 = m2;
у m1 размер был меньше, то произойдет ошибка, т.к. выделено недостаточно памяти. Можно, допустим, проверить размер, и если он не совпадает, то выделить память по новой
C++
1
2
3
delete [] mas;
size = m2.size;
mas = new int[size];
Еще в операторе присваивания нужна проверка на присваивание объекта самому себе:
C++
1
2
if(this == &mas2) // если адреса объектов справа и слева от = совпадают, значит это один и тот же объект
    return *this;
Добавлено через 3 минуты
Цитата Сообщение от Grinning liar Посмотреть сообщение
что элементы умножаемой матрицы и конечной разные (и соответственно находятся в разных местах памяти), оба указателя хранят адрес начала исходной матрицы?
Умножаемая и конечная матрица будут хранить разные указатели и разные элементы. Но если написать:
m1 = m2, то указатели mas в обоих этих объектах будут содержать один и тот же адрес. Так как выполнится m1.mas = m2.mas (а надо копировать поэлементно)
1
Grinning liar!
3 / 3 / 0
Регистрация: 01.11.2012
Сообщений: 38
30.12.2012, 19:39  [ТС] #8
А разве нужна проверка на размерность? Мы ведь везде используем одно и то же входное значение size, которое задаем в первую очередь - матрицы ж не могут получиться разных размеров.
Спасибо за помощь!
0
Schizorb
510 / 462 / 82
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
Завершенные тесты: 1
30.12.2012, 19:51 #9
Цитата Сообщение от Grinning liar Посмотреть сообщение
матрицы ж не могут получиться разных размеров
Как не могут? Допустим, вы создали две матрицы (на самом деле для этого лучше сделайте конструктор с параметром-размер, вместо функции create_mas).

C++
1
2
m1.create_mas(5); 
m2.create_mas(10);
А потом присвоили m1 = m2; В m1 выделена память всего под 5 элементов, а в цикле (который у вас в перегруженном операторе) вы присваиваете аж 10 элементов.
0
Grinning liar!
3 / 3 / 0
Регистрация: 01.11.2012
Сообщений: 38
31.12.2012, 03:59  [ТС] #10
И последний вопрос, если можно: пытаюсь описать деструктор класса, который высвобождает зарезервированную память после уничтожения объекта. Насколько я понял - когда уничтожить объект класса, компилятор понимает сам и вызывать деструктор (как и конструктор) в явном виде не надо. Описываю так, но при выполнении программы ошибит:
C++
1
2
3
4
5
6
Matrix::~Matrix() {
    
    for (int i = 0; i < size; i++) {
        delete [] mas[i];
    }
    delete [] mas;
0
Schizorb
510 / 462 / 82
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
Завершенные тесты: 1
31.12.2012, 07:04 #11
Цитата Сообщение от Grinning liar Посмотреть сообщение
в явном виде не надо
Да, явно не надо вызывать. В деструкторе не вижу ошибки. Может она есть в конструкторе или других методах, где память выдляется? Примерно так можно сделать конструктор с 1 параметром:
C++
1
2
3
4
5
6
7
8
9
10
11
12
Matrix::Matrix(int sz)
{
    size = sz;  // сохраняем размер
    
    mas = new float * [size];    //выделяем память на массив указателей начал строк массива
 
    for(int i = 0; i < size; i++)   //выделение памяти на каждую строку массива
    {
        mas[i] = new float [size];
    }
    
}
1
31.12.2012, 07:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.12.2012, 07:04
Привет! Вот еще темы с решениями:

Перегрузка оператора <<
Есть такой код. class matrix { public: ......; const double*...

Перегрузка оператора ==
Пытаюсь перегрузить оператор == . Делаю так: В классе: class cData // класс...

Перегрузка оператора +
Не могу заставить работать перегруженный оператор + в функции CMoveByVector ...

Перегрузка оператора
Всем доброго времени суток!Помогите пожалуйста! Перегрузил оператор умножения...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

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