С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
Anvis
38 / 16 / 5
Регистрация: 06.06.2013
Сообщений: 75
1

Перегрузить операторы operator+() и operator*() в пользовательском классе "Комплексное число"

20.01.2016, 00:30. Просмотров 737. Ответов 25
Метки нет (Все метки)

Здравствуйте. Предлагаю заняться арифметикой.

Создал прослейший класс, перегрузил операторы сложения и умножения, в конструкторе произвожу вычисления. Строка 12 и 14 работают, а строка 13 выдает ошибку:
no match for 'operator+' in 'x + x.complex::operator*((* & z))'
Почему?

C++
1
2
3
4
5
6
7
8
9
10
class complex
{
public:
    complex();
 
    double re, im;
 
    complex operator+ (complex& z2);
    complex operator* (complex& z2);
};
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
#include "complex.h"
 
complex::complex()
{
    complex z, x;
 
    z.re = 1;
    z.im = 2;
    x.re = 1;
    x.im = 2;
 
    z = x+x;
    z = x+x*x;
    z = x*x+x;
}
 
complex complex::operator+ (complex& z2)
{
    complex z1;
    z1.re = z1.re + z2.re;
    z1.im = z1.im + z2.im;
    return z1;
}
complex complex::operator* (complex& z2)
{
    complex z1;
    z1.re = (z1.re * z2.re) - (z1.im * z2.im);
    z1.im = (z1.re * z2.im) + (z1.im * z2.re);
    return z1;
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.01.2016, 00:30
Ответы с готовыми решениями:

Перегрузить "operator -" так, чтобы из вектора удалялся элемент, присутствующий во втором векторе
#include "stdafx.h" #include <conio.h> #include <iostream> #include <string>...

Перегрузка оператора operator+() в пользовательском классе (сложение строк)
Хотел научить класс складывать строки, но на моменте освобождения памяти temp...

Ошибка при перегрузке "operator ==" в классе
Если объявляю operator== в классе, то ошибка слишком много параметров для...

Чем "operator *=" отличается от "operator *"?
снова застряла, не могу понять, чем этот оператор должен отличаться от...

Добавить целое число в очередь с помощью "operator <<"
В общем, прочитал я статьи про очереди. Где делается с помощью...

25
anti-k
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
Завершенные тесты: 1
20.01.2016, 00:40 2
Лучший ответ Сообщение было отмечено Anvis как решение

Решение

C++
1
complex& complex::operator+ (complex& z2)
1
Lawliet1
29 / 32 / 18
Регистрация: 30.09.2011
Сообщений: 202
Завершенные тесты: 1
20.01.2016, 00:42 3
а можно весь код? я допустим слабо понимаю что происходит, когда мы создаем
C++
1
complex z1;
... в z1.re и в z1.im мусор? так и должно быть?
0
Anvis
38 / 16 / 5
Регистрация: 06.06.2013
Сообщений: 75
20.01.2016, 00:48  [ТС] 4
Lawliet1, конечно не должно. У меня случайно нажался энтер при создании темы, пришлось быстро-быстро ее редактировать, потом попытки отредактировать истекли... Вот исправленный вариант:

C++
1
2
3
4
5
6
7
8
9
10
class complex
{
public:
    complex();
 
    double re, im;
 
    complex operator+ (complex& z);
    complex operator* (complex& z);
};
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
#include "complex.h"
 
complex::complex()
{
    complex z, x;
    
    z.re = 1;
    z.im = 2;
    x.re = 1;
    x.im = 2;
 
    z = x+x;
    z = x+x*x;
    z = x*x+x;
}
 
complex complex::operator+ (complex& z)
{
    complex z1;
    z1.re = re + z.re;
    z1.im = im + z.im;
    return z1;
}
complex complex::operator* (complex& z)
{
    complex z1;
    z1.re = (re * z.re) - (im * z.im);
    z1.im = (re * z.im) + (im * z.re);
    return z1;
}
0
anti-k
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
Завершенные тесты: 1
20.01.2016, 00:54 5
Lawliet1,
z1 получается автоматическая переменная, которая прям там и умирает,
как бэ должо быть так
C++
1
2
complex*z1=new complex(re+=z2.re);
и возвращаем ссылочку
Добавлено через 2 минуты
Anvis,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
complex::complex()
{
    complex z, x;
    
    z.re = 1;
    z.im = 2;
    x.re = 1;
    x.im = 2;
 
    z = x+x;
    z = x+x*x;
    z = x*x+x;
}
Что это
0
Lawliet1
29 / 32 / 18
Регистрация: 30.09.2011
Сообщений: 202
Завершенные тесты: 1
20.01.2016, 00:57 6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
complex::complex()
{
    complex z, x;
    
    z.re = 1;
    z.im = 2;
    x.re = 1;
    x.im = 2;
 
    z = x+x;
    z = x+x*x;
    z = x*x+x;
}
я такое у себя запускать не очень хочу.. я может и ошибаюсь, но создавая в конструкторе объекты этого же класса мы снова вызываем конструктор и так до посинения...

Добавлено через 2 минуты
anti-k, во-во бесконечная рекурсия
0
Anvis
38 / 16 / 5
Регистрация: 06.06.2013
Сообщений: 75
20.01.2016, 01:16  [ТС] 7
Да, правильно. Конечно, в "боевой" программе в конструкторе класса нет ничего кроме инициализации полей, а все операции производятся в другом. Спешил, когда правил тему

Исправил определения методов на код ниже, все операции стали выполняться как положено. anti-k, спасибо, проблема решена, а мне надо доучить использование указателей.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
complex& complex::operator+ (complex& z)
{
    complex*z1=new complex();
    z1->re = re + z.re;
    z1->im = im + z.im;
    return *z1;
}
complex& complex::operator* (complex& z)
{
    complex*z1=new complex();
    z1->re = (re * z.re) - (im * z.im);
    z1->im = (re * z.im) + (im * z.re);
    return *z1;
}
0
avgoor
1044 / 611 / 158
Регистрация: 05.12.2015
Сообщений: 1,739
20.01.2016, 14:57 8
Лучший ответ Сообщение было отмечено Anvis как решение

Решение

Цитата Сообщение от Anvis Посмотреть сообщение
complex& complex::operator+ (complex& z)
C++
1
2
3
4
5
{
 complex*z1=new complex();
 z1->re = re + z.re;
 z1->im = im + z.im;
 return *z1;
}
Бинарные арифметические операторы лучше так не перегружать, а возвращать из них ссылку вообще за гранью добра и зла.

Лучше так:
C++
1
2
3
4
const complex operator+(const complex& l, const complex & r)
{
    return complex(l.re+r.re, l.im+r.im);
}
2
rikimaru2013
C++ Game Dev
2473 / 1141 / 349
Регистрация: 30.11.2013
Сообщений: 3,709
20.01.2016, 15:10 9
Цитата Сообщение от anti-k Посмотреть сообщение
complex*z1=new complex(re+=z2.re);
и возвращаем ссылочку

C++
1
Foo f = a + b + c + d;
угадайте сколько тут будет утечек памяти?)
1
anti-k
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
Завершенные тесты: 1
20.01.2016, 15:18 10
rikimaru2013,
Деструктор ситуацию не исправит?
0
rikimaru2013
C++ Game Dev
2473 / 1141 / 349
Регистрация: 30.11.2013
Сообщений: 3,709
20.01.2016, 15:22 11
Цитата Сообщение от anti-k Посмотреть сообщение
Деструктор ситуацию не исправит?
нет конечно же - при вызове деструктора для ссылки не вызывается деструктор объекта на который он ссылался, тоже самое и для указателя) тут ответ как надо Перегрузить операторы operator+() и operator*() в пользовательском классе "Комплексное число" и надо(для меня надо, а по факту желательно) перегрузить вне класса.
2
avgoor
1044 / 611 / 158
Регистрация: 05.12.2015
Сообщений: 1,739
20.01.2016, 15:45 12
Цитата Сообщение от anti-k Посмотреть сообщение
Деструктор ситуацию не исправит?
Деструктор вызывается при удалении объекта (оператором delete или при выходе из области видимости) и не связан с удалением памяти, занимаемой объектом. Он для освобождения ресурсов, которые объект захватил (например сам объект выделил память).
При выходе ссылки из области видимости деструктор вообще не вызывается.
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
при вызове деструктора для ссылки не вызывается деструктор объекта на который он ссылался
Ссылка - это сущность времени компиляции. Никакого деструктора для ссылки даже теоретически существовать не может.
1
anti-k
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
Завершенные тесты: 1
20.01.2016, 15:57 13
avgoor, не пинайте сильно, я новичок.
Цитата Сообщение от avgoor Посмотреть сообщение
const complex operator+(const complex& l, const complex & r)
{
* * return complex(l.re+r.re, l.im+r.im);
}
В случае этого return-a создается не именованная временная переменная(если я правильно понимаю), теперь я понимаю что передавать по ссылке низзя, но что именно происходит в этом случае?
0
avgoor
1044 / 611 / 158
Регистрация: 05.12.2015
Сообщений: 1,739
20.01.2016, 16:08 14
Цитата Сообщение от anti-k Посмотреть сообщение
но что именно происходит в этом случае?
Например
C++
1
2
complex a(1,1), b(1,1);
complex c=a+b
Здесь во второй строке все зависит от того, какие конструкторы определены. Возможно:
1) Создастся временный объект, вызовется конструктор копирования для с, вызовется деструктор для временного объекта.
2) Создастся временный объект, вызовется перемещающий конструктор для с.
3) Применится RVO: Вызовется конструктор (double, double) для c.

Скорее всего 3).
1
anti-k
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
Завершенные тесты: 1
20.01.2016, 16:11 15
avgoor,
А почему оптимизирует приводя к double?
Цитата Сообщение от avgoor Посмотреть сообщение
Применится RVO: Вызовется конструктор (double, double) для c.
0
avgoor
1044 / 611 / 158
Регистрация: 05.12.2015
Сообщений: 1,739
20.01.2016, 16:15 16
Цитата Сообщение от anti-k Посмотреть сообщение
А почему оптимизирует приводя к double?
Имеется ввиду, что строка: return complex(l.re+.... применится сразу к с, а не ко временному объекту - это и есть RVO.
0
anti-k
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
Завершенные тесты: 1
20.01.2016, 16:19 17
avgoor, Я так понимаю что вроде как временный объект получает имя с и сам становится с?
0
avgoor
1044 / 611 / 158
Регистрация: 05.12.2015
Сообщений: 1,739
20.01.2016, 16:26 18
Нет, временный объект вообще не создается. Т.е. Вот это:
C++
1
2
complex a(1,1), b(1,1);
complex c=a+b;
превращается в это:
C++
1
2
complex a(1,1), b(1,1);
complex c(a.re+b.re, a.im+b.im);
1
anti-k
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
Завершенные тесты: 1
20.01.2016, 16:30 19
avgoor, Спасибо!!!
0
Anvis
38 / 16 / 5
Регистрация: 06.06.2013
Сообщений: 75
20.01.2016, 19:09  [ТС] 20
Подведу итог.

complex.h
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
class complex
{
public:
    complex();
    complex(double a, double b);
 
    double re, im;
};
 
const complex operator+ (const complex& z1, const complex& z2);
const complex operator* (const complex& z1, const complex& z2);


complex.cpp
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "complex.h"
 
complex::complex()
{
    re = 0;
    im = 0;
}
complex::complex(double a, double b)
{
    re = a;
    im = b;
}
 
const complex operator+ (const complex& z1, const complex& z2)
{
    return complex(z1.re+z2.re, z1.im+z2.im);
}
const complex operator* (const complex& z1, const complex& z2)
{
    return complex((z1.re * z2.re) - (z1.im * z2.im), (z1.re * z2.im) + (z1.im * z2.re));
}


Почему перегружать вне класса понял и автоматически получил ответ на другой вопрос. Спасибо.
Цитата Сообщение от avgoor Посмотреть сообщение
Бинарные арифметические операторы лучше так не перегружать, а возвращать из них ссылку вообще за гранью добра и зла.
Кстати, почему? Ведь в примерах из книг по этой теме действительно возвращаются ссылки, и с ними все работало.
0
20.01.2016, 19:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.01.2016, 19:09

Expected init-declarator before "operator".expected `,' or `;' before "operator"
Пример не мой. Пытаюсь у себя запустить и чтото неполучается. Ошибка на строке...

Перегрузить операторы "=", "+=" так, чтобы производилось сложение строки и объекта
помогите ,пожалуйста вот задание:Реализовать класс String для работы со...

Подскажите как перегрузить операторы ">>", "<<" и "="
Кто знает, подскажите как перегрузить операторы &quot;&gt;&gt;&quot;, &quot;&lt;&lt;&quot; и &quot;=&quot; ?


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

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

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