67 / 65 / 61
Регистрация: 11.11.2015
Сообщений: 392
|
||||||||||||||||
1 | ||||||||||||||||
Как правильно перегружать операторы?22.09.2016, 22:03. Показов 3363. Ответов 14
Метки нет (Все метки)
Добрый день. Более-менее освоил Си, и вроде бы неплохо в нем разбираюсь. Решил взяться за плюсы.
Помогите разобраться с перегрузкой операторов. Я понял, что существуют разные виды перегрузки (как дружественная функция, как функция-член класса). Но когда и какой способ предпочтительно использовать? Вот есть у меня некий класс
Ну и чтобы можно было пользоваться оператором +=? Заранее спасибо.
0
|
22.09.2016, 22:03 | |
Ответы с готовыми решениями:
14
Как же все-таки лучше всего перегружать операторы? Как правильно перегружать оператор? Как правильно перегружать унарный минус? какие операторы нельзя перегружать? |
7803 / 6567 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
|
22.09.2016, 22:06 | 2 |
Как функцию-член класса реализуй. Дружественная только для ввода/вывода, с потоками.
2
|
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
|
||||||
22.09.2016, 22:24 | 3 | |||||
Сообщение было отмечено lonelyhunter как решение
Решение
1
|
67 / 65 / 61
Регистрация: 11.11.2015
Сообщений: 392
|
|
22.09.2016, 22:39 [ТС] | 4 |
А почему для += нужно возвращать ссылку, а для + константу?
0
|
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
|
||||||
22.09.2016, 22:55 | 6 | |||||
Такое поведение определено для встроенных типов в С++ и по логике наш оператор += (и все другие операторы присваивания) тоже должен это делать.
Защита от такого кода:
1
|
67 / 65 / 61
Регистрация: 11.11.2015
Сообщений: 392
|
||||||
22.09.2016, 22:58 [ТС] | 7 | |||||
В C++ в таком случае что происходит? (21 строка)
0
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
||||||
22.09.2016, 23:07 | 8 | |||||
Потому что для + ссылка будет на локальную переменную (на аргументы нельзя - плюс их не меняет) и сдохнет сразу по завершении оператора.
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
22.09.2016, 23:16 | 9 |
Сообщение было отмечено gru74ik как решение
Решение
Добрый вечер,
давайте разбираться - имеем 2 способа перегрузки операторов: 1) в классе 2) вне класса. Прежде чем говорить о выборе того или другого способа давайте обсудим операторы, которые можно перегрузить только в один способ: а) Перегрузить только как член класса можно: - operator = - operator () - operator[] - operator -> - operator new - operator delete Заметим, что операторы new и delete перегружаются только как статические методы класса - ведь без объекта можно вызвать только статические. А тут важная критерия "без объекта" особенно для оператора new - думаю вы понимаете. б) Перегружать только глобально: - сюда относится только 1 тип операторов, и вопрос я считаю сложным (лично я его и завалил на испыте и получил 11, а не 12 Ответ в спойлере Кликните здесь для просмотра всего текста
Операторы левый оперант, которых фундаментальный тип или другой пользовательский тип
И так мы определились с правилами без которых ни куда. Далее есть рекомендация от создателя языке С++: "Если оператор подразумевает изменение объекта - его стоит перегрузить как член-класса, в противном случаи - через глобальную функцию" Поэтому если у вас встанет вопрос, какой же выбрать - вспомните эту рекомендацию. Теперь третий и последний вопрос: мы уже определились, что оператор будет перегружен как глобальная функция, но данный оператор является неотъемлемой частью класса в частности оператор вывода/ввода - так как левый оперант у нас "неправильный" и мы вынуждены перегрузить только глобально, то встаёт вопрос - сколько сеттеров/геттеров нужно будет вызвать в этих операторах - хотя эту функцию будет писать тот же программист, и объявлена она будет в том же файле, где и класс. Поэтому очень часто этой функции предоставляют карт-бланш делая её дружественной. Тем самым мы архитектурно говорим, что она наша - просто сложились такие обстоятельства, что она снаружи класса.
3
|
67 / 65 / 61
Регистрация: 11.11.2015
Сообщений: 392
|
|
22.09.2016, 23:30 [ТС] | 10 |
Спасибо, буду разбираться дальше.
0
|
Вездепух
12792 / 6669 / 1795
Регистрация: 18.10.2014
Сообщений: 16,882
|
|
22.09.2016, 23:48 | 11 |
Во-первых, немодифицирующие операторы с симметричными (по типу) операндами (типа бинарных арифметических), рекомендуется реализовывать отдельностоящей [friend] функцией, а не членом класса. Членом класса обычно реализуются только модифицирующие операторы (типа
+= или ++ )Во-вторых, чтобы два раза не делать одно и то же, устойчивой идиомой является реализация бинарного + через += .
0
|
67 / 65 / 61
Регистрация: 11.11.2015
Сообщений: 392
|
|
23.09.2016, 09:35 [ТС] | 12 |
Интересно. Мнения разделились. Выходит строгих правил нет.
0
|
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
|
||||||
23.09.2016, 10:01 | 13 | |||||
Важно подчеркнуть, что, если инициализировать второй и третий параметры конструктора значениями по умолчанию, то складывать скаляр с вектором можно будет только если функция сложения определена не как член класса:
Добавлено через 1 минуту В чем же, по-вашему?
0
|
67 / 65 / 61
Регистрация: 11.11.2015
Сообщений: 392
|
|
23.09.2016, 10:03 [ТС] | 14 |
Ну выше была рекомендация использовать дружественные функции, только для работы с потоками. < >
0
|
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
|
|
23.09.2016, 12:49 | 15 |
Не знаю, где вы это вычитали, здесь вроде бы все согласились, что
Саттер и Александреску в своей книге "Стандарты программирования на С++" рекомендуют предпочитать функции, которые не являются ни членами, ни друзьями (рекомендации 27 и 44). На самом деле это одно из применений основного принципа ООП - всемерной минимизации взаимозависимостей.
1
|
23.09.2016, 12:49 | |
23.09.2016, 12:49 | |
Помогаю со студенческими работами здесь
15
Как правильно перегружать потоковый оператор вывода в файл? Для енама нельзя перегружать операторы? Как правильно записывать условные операторы и как прервать проверку при достижении результата? Как правильно перегрузить операторы для собственных классов? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |