![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| kkkggg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 28.4.2006 Репутация: нет Всего: нет |
Я не могу понять как, описать operator+.
#include <iostream.h> class complex { public: int r,i; complex(int re, int im):r(re),i(im) {} complex operator+(complex); }; complex complex::operator+(complex a) { // Что сдесь нужно писать? } int main() { complex a = complex(1,3); complex b = complex(6,8); complex c = a + b; return 0; } Помогитье довести данный пример до ума... |
|||
|
||||
| Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
Для справки: есть std::complex |
|||
|
||||
| kkkggg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 28.4.2006 Репутация: нет Всего: нет |
Теперь довайте разбираться
complex& operator+(const complex&); Что означает "&" ? Я помню что это раздел "Указатели", и называется он амперсент. Простой пример его использования: char c = 'a'; char *p = &c; // Теперь *р хранит адрес переменной с. Я непойму зачем он ставится после типа в нашем примере? |
|||
|
||||
| Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
kkkggg, да, ты прав - это амперсанд. Открой раздел ссылки
|
|||
|
||||
| Prehistorik |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 146 Регистрация: 30.5.2006 Где: СПб Репутация: 1 Всего: 3 |
В списке параметров он ставится для того, чтобы не забивать стек. А вот после возращаемого типа для тогго же....
А вот это не совсем верно. Потому как в примере
переменная "a" теперь содержит значение (7,11)... по мне, так надо вот так....
--------------------
Есть только один бог - Ассемблер, и С - пророк его. |
||||||||
|
|||||||||
| Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
||||
|
||||
| Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
А теперь подумай, на что ты возвращаешь ссылку, и почему это работать не будет. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Правильный оператор "+" должен возвращать не ссылку, а значение.
И быть константным. Или вообще реализовываться вне класса. И, конечно, не менять значений своих аргументов. Таким как написано выше должен быть оператор +=
-------------------- ... |
|||
|
||||
| AlanG |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 11.5.2006 Где: РашЫн ФидирейшЫн Репутация: нет Всего: нет |
Логика operator+. следующая:
Действия производимые над объектами типа + (сложение), например: complex c = a + b; вызывают этот оператор(можно сказать функция). Поисходит следующее: объект a генерирует вызов operator+( const complex b), при этом втророй объект (b) посылается в эту функцию в качестве аргумента: complex c = a + b;
Это сообщение отредактировал(а) AlanG - 15.6.2006, 18:45 |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
AlanG, это ты написал, как не надо делать, я надеюсь?
Не говоря уж о том, что код компилироваться не будет (путаешь ссылки с указателями). А еще, в С++ функции редко "возбуждаются", это делают все больше исключения. -------------------- ... |
|||
|
||||
| AlanG |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 11.5.2006 Где: РашЫн ФидирейшЫн Репутация: нет Всего: нет |
Дополню: В функцию неявно передается сылка на вызываемый объект, т.е. а в данном случае, к этому объекту и к его членам, например в твоем классе complex ты указал переменные r и i, к этим членам можно обратится на "прямую", не указываея объект.
От себя: Лично мне нравится логика operator, она очень проста в понимании, и может пригодится в повседневной работе программисат. Добавлено @ 18:58
Я не смотрю на код, я простопытаюсь логику выделить Может код ошибочный но не в этом суть. |
||||
|
|||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
AlanG, ты извини, но такими объяснениями ты новичка вообще запутаешь.
kkkggg, правильный оператор + должен быть таким (2 варианта):
Второй вариант лучше, т.к. позволяет компилятору выполнить преобразование левого операнда (скажем из ... тьфу, только сейчас заметила, что у тебя реальная и мнимая части представлены как целые -------------------- ... |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
все равно operator+ лучше реализовывать через operator+=
тем более, что его, имхо, обязательно нужно реализовывать (тем более в случае complex) -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Никто и не спорит.
-------------------- ... |
|||
|
||||
| AlanG |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 11.5.2006 Где: РашЫн ФидирейшЫн Репутация: нет Всего: нет |
Можно по подробнее про реальную и мнимую часи И про преобразование левого операнда. |
|||
|
||||
| Earnest |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Да вот же код класса с интами в качестве реальной и мнимой частей:
Если определено преобразование из double в complex (например, не explicit конструктор с один аргументом double), то в таком случае:
компилятор сможет использовать оператор сложения комплексных чисел только в том случае, если он определен как внешний. А с точки зрения математики такая запись вполне естественна и не должна зависеть от порядка аргументов. -------------------- ... |
||||
|
|||||
| AlanG |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 11.5.2006 Где: РашЫн ФидирейшЫн Репутация: нет Всего: нет |
Реальное здесь переменные r и i, а мнимое, их инициализация (:r(re),i(im) {} )что ли? Чет не вкурю логику
Определено программой или пользователем? Если пользователем, то как?
А я считал что будет работать из-за того что второй аргумент является типом[ B]complex[/B], Оператор ветдь принимает тип complex. Или я ошибаюсь Можно по подробнее описывать, а то я моло что понимаю |
||||||
|
|||||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
программу пишет программист
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Если сложение реализовано как метод класса complex, то преобразовать a (которое у нас double) в комплекс, а потом вызвать для него operator + компилятор не догадается. А для double оператора + (complex) нет. То, как компилятор разрешает перегруженные имена, называется поиском Кенига. Во многих книгах по C++ это описано, почитай, весьма полезно. Вкратце, компилятор начинает с поиска подходящего метода класса. Если не нашел, ищет глобальный оператор в данной области действия (scope). И т.д. Важно то, что при поиске методов класса компилятор использует точный тип левого операнда. Т.е. методы класса complex вообще проверяться не будут, т.к. левый операнд у нас double. -------------------- ... |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
Я полагаю поиск Кенига - это поиск имен в пространстве имен аргумента Т. е если параметр принадлежит какому-то пространству имен и вызывается функция с этим параметром в качестве аргумента, то перегрузка идет с учетом поиска этой функции в этом пространстве имен -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
В общем случае такой подход, как мне кажется, не очень-то хорош. Если требуется безопасный в отношении исключений код (в данной задаче это неактуально), то в operator+= появятся накладные расходы по сохранению старого значения, которые совершенно незачем переносить в operator+. Если же делать наоборот (operator+= реализовывать через operator+), то в данной задаче имеем лишнее копирование в operator+=. Так что если хочется общности, то лучше использовать стороннюю функцию и выражать оба оператора через неё:
Это сообщение отредактировал(а) UnrealMan - 17.6.2006, 18:01 |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
||||
|
||||
| AlanG |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 11.5.2006 Где: РашЫн ФидирейшЫн Репутация: нет Всего: нет |
И все таки: Определение operator + () в классе предполагает (нужна для) обработку при соответствующих действиях (типа + (сложение) или / (деление)) над объектами соответствующего класса??? При чем вызываются эти операторы обычно левым оператором (вернее operatorу() неявно передается ссылка на этот объект), при бинарной операции? Т.е. это как команда для компилятора, что нужно совершить те действия которые объявлены в теле operato+(). Это сообщение отредактировал(а) AlanG - 17.6.2006, 13:44 |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Что ещё за левый оператор такой? :-) Наверно, ты имел в виду левый операнд, но тогда не понятно, как это операнд может вызывать оператор :-) Для данного найденного в коде плюсика ищется соответствующий (наиболее подходящий – исходя из количества операндов, а также их типов) operator+. А вообще да будет Страуструп тебе в помощь. |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Это общепринятая идиома: оператор + не изменяет своих операндов - т.е. является константным, если определяется как метод.
Насколько я помню, это принцип поиска имен в С++ вообще, в том числе и то, что ты сказал. -------------------- ... |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
||||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
Поиск Кенига понятие более конкретное в отличие от просто "поиск" -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Возвращаемое значение делают константным, чтобы ему нельзя было присваивать, т.е. компилятор ругался на конструкции типа a+b = f; С моей точки зрения это из разряда "святее папы римского", т.е. не слишком обязательно. -------------------- ... |
|||
|
||||
| AlanG |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 11.5.2006 Где: РашЫн ФидирейшЫн Репутация: нет Всего: нет |
Ну это понятно.
Уже помогает, купил >1000 страниц логического счястья |
||||
|
|||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: 1 Всего: 3 |
UnrealMan, ставлю плюсик, но по моему не освещён вопрос о том, что плюс может быть в выражении с = (а+б+с)*в+..., то есть когда в формуле участвуют несколько операторов
-------------------- я не гольфист - я хоккеист |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Там же: 3.2 Сводка операций Там, правда, есть небольшая ошибочка в приоритетах: постфиксные инкремент и декремент на самом деле имеют тот же приоритет, что и [] (а также другие операторы в этой группе), а sizeof expr, напротив, имеет меньший приоритет (такой же, как у префиксного инкремента и т.д.) |
|||
|
||||
| kkkggg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 28.4.2006 Репутация: нет Всего: нет |
Проблема в вычислениях, когда d = a+b всё ок, а когда d = a+b+c, вот тут проблема. Посмотрите что не так, может оператор я не доконца определил? |
|||
|
||||
| AlanG |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 11.5.2006 Где: РашЫн ФидирейшЫн Репутация: нет Всего: нет |
Наверно так, думаю что надо еще один аргумент определить в операторе, если ты конечно хочешь принимать два аргумента. Кстати напомню, что в оператор кроме аргументов передается еще и ссылка на вызывающий объект, т.е. в данном случае это объект d, он передается не явно, и ссылатся на него можно с помощъю this в теле оператора.
Все таки у тебя он определен один, с принимающими аргументами в одном кол-ве (const complex& ARG). Можно в принципе определить несколько, с разным кол-вом аргументов, и тогда компилятор сам выберет самый подходящий оператор:
Это сообщение отредактировал(а) AlanG - 28.6.2006, 07:59 |
||||||
|
|||||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |