С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
Grinning liar!
3 / 3 / 0
Регистрация: 01.11.2012
Сообщений: 38
#1

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

27.12.2012, 00:32. Просмотров 785. Ответов 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++):

Перегрузка оператора [] - C++
Всем привет! Как можно перегрузить оператор так, чтобы к нему можно было обращаться так: class_arr = 5; Где class_arr - переменная...

Перегрузка оператора << - C++
Вот упрощенный вариант моей программы, пересчитывает время в 12-й формат мне нужно перегрузить оператор &lt;&lt; так, чтобы time_cycle_1&lt;&lt;(1);...

Перегрузка оператора + - C++
не получается в своем классе перегрузить оператор + :( пишет &quot;error C2804: бинарный &quot;operator +&quot; имеет слишком много параметров&quot;,...

Перегрузка оператора - C++
Помогите доделать задание... Это в классе метод, осуществляющий ввод значений полей класса с клавиатуры; метод, осуществляющий...

Перегрузка оператора - C++
Здравствуйте. Нужна помощь) Есть такой класс: class vect { public: float *items; vect() { items = new float; for(int...

Перегрузка оператора + - C++
Здравствуйте. Проблема в следующем: у меня есть класс. Список, реализующий работу с полиндромом: struct Field { int a; int...

10
Schizorb
510 / 462 / 16
Регистрация: 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 / 16
Регистрация: 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 / 16
Регистрация: 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 / 16
Регистрация: 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 / 16
Регистрация: 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
Привет! Вот еще темы с ответами:

Перегрузка оператора * - C++
Операция произведения применяется к объекту квадрат, при этом изменяются координаты центры фигуры. Результатом произведения является...

Перегрузка оператора + - C++
Не могу заставить работать перегруженный оператор + в функции CMoveByVector Point.h: #define POINT_H #include &lt;iostream&gt; ...

Перегрузка оператора - C++
#include &lt;iostream&gt; class Node { public: char *s; int length; Node * next; public: Node(); Node(char* val) {

Перегрузка оператора - C++
Здравствуйте. Не могу разобраться, как перезагрузить оператор &gt;&gt;. int a; cin &gt;&gt; a; Надо, чтобы a умножалось на некое число,...


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

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

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