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

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

20.01.2016, 00:30. Показов 2504. Ответов 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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.01.2016, 00:30
Ответы с готовыми решениями:

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

Перегрузка operator>> и operator<< в абстрактном классе
Здрасьте! Есть необходимость перегрузить потоки, Я знаю как это сделать через friend, но вот кажется что есть и другое решение. Попытался...

Для класса "Комплексное число" перегрузить операторы
Реализация класса для комплексного числа Для класса &quot;Комплексное число&quot; перегрузите операторы C1=C2 += (С1+= С2) &lt; (С1&lt; С2)​ ...

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

Решение

C++
1
complex& complex::operator+ (complex& z2)
1
31 / 34 / 18
Регистрация: 30.09.2011
Сообщений: 202
20.01.2016, 00:42
а можно весь код? я допустим слабо понимаю что происходит, когда мы создаем
C++
1
complex z1;
... в z1.re и в z1.im мусор? так и должно быть?
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
20.01.2016, 00:48  [ТС]
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
20.01.2016, 00:54
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
31 / 34 / 18
Регистрация: 30.09.2011
Сообщений: 202
20.01.2016, 00:57
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
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
20.01.2016, 01:16  [ТС]
Да, правильно. Конечно, в "боевой" программе в конструкторе класса нет ничего кроме инициализации полей, а все операции производятся в другом. Спешил, когда правил тему

Исправил определения методов на код ниже, все операции стали выполняться как положено. 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
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
20.01.2016, 14:57
Лучший ответ Сообщение было отмечено 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
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
20.01.2016, 15:10
Цитата Сообщение от 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
20.01.2016, 15:18
rikimaru2013,
Деструктор ситуацию не исправит?
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
20.01.2016, 15:22
Цитата Сообщение от anti-k Посмотреть сообщение
Деструктор ситуацию не исправит?
нет конечно же - при вызове деструктора для ссылки не вызывается деструктор объекта на который он ссылался, тоже самое и для указателя) тут ответ как надо Перегрузить операторы operator+() и operator*() в пользовательском классе "Комплексное число" и надо(для меня надо, а по факту желательно) перегрузить вне класса.
2
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
20.01.2016, 15:45
Цитата Сообщение от anti-k Посмотреть сообщение
Деструктор ситуацию не исправит?
Деструктор вызывается при удалении объекта (оператором delete или при выходе из области видимости) и не связан с удалением памяти, занимаемой объектом. Он для освобождения ресурсов, которые объект захватил (например сам объект выделил память).
При выходе ссылки из области видимости деструктор вообще не вызывается.
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
при вызове деструктора для ссылки не вызывается деструктор объекта на который он ссылался
Ссылка - это сущность времени компиляции. Никакого деструктора для ссылки даже теоретически существовать не может.
1
 Аватар для anti-k
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
20.01.2016, 15:57
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
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
20.01.2016, 16:08
Цитата Сообщение от 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
20.01.2016, 16:11
avgoor,
А почему оптимизирует приводя к double?
Цитата Сообщение от avgoor Посмотреть сообщение
Применится RVO: Вызовется конструктор (double, double) для c.
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
20.01.2016, 16:15
Цитата Сообщение от anti-k Посмотреть сообщение
А почему оптимизирует приводя к double?
Имеется ввиду, что строка: return complex(l.re+.... применится сразу к с, а не ко временному объекту - это и есть RVO.
0
 Аватар для anti-k
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
20.01.2016, 16:19
avgoor, Я так понимаю что вроде как временный объект получает имя с и сам становится с?
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
20.01.2016, 16:26
Нет, временный объект вообще не создается. Т.е. Вот это:
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
20.01.2016, 16:30
avgoor, Спасибо!!!
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
20.01.2016, 19:09  [ТС]
Подведу итог.

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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.01.2016, 19:09
Помогаю со студенческими работами здесь

Перегрузить operator*
Подскажите, пожалуйста, как использовать operator* в void main в данной программе по аналогии с operator-&gt; Не разобрался полностью в...

Не могу нормально перегрузить operator <
Написал функцию f1, внутри которой используется std::sort. Вне этой функции перегрузил operator &lt; для string. Не подскажете, почему...

Перегрузить operator* для комплексных чисел
Нужно определить бинарный или унарный оператор a*b для комплексных чисел

Перегрузка операторов operator> и operator* для чисел в разных системах счисления
Мне нужно Перегрузить операции&gt; (сравнение двух целых чисел с учетом системы счисления), * (произведение таких чисел). Но я не могу понять...

Почему в данном случае используется operator int, а не operator double?
Вот программа using System; class ThreeD { int x, y, z; // трехмерные координаты public ThreeD() { x = y = z = 0; } ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru