Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
 Аватар для gore-lykovoe
32 / 32 / 3
Регистрация: 04.04.2010
Сообщений: 414

Как же все-таки лучше всего перегружать операторы?

08.09.2013, 01:31. Показов 1401. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
1. Нужно ли использовать friend там, где это возможно? (или не стоит злоупотреблять где-нибудь?)
2. Стоит ли при перегрузке бинарного оператора "+" делать его обособленным от класса?
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
// свободная ф-ия которая не friend для класса DATES
// она просто использует публичный оператор operator +=
DATES operator + (const DATES& lhs, const DATES& rhs)
{
  DATES result(lhs);
  result += rhs; // заиспользовали публичный оператор +=
  return result;
}


Оператор присваивания и копирующий конструктор обсуждать не нужно - с ними все понятно.

Интересно ваше мнение насчет перегрузок взятых из статьи на хабре:
Кликните здесь для просмотра всего текста
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class Integer
{
private:
    int value;
public:
    Integer(int i): value(i) 
    {}
 
    //унарный +
    friend const Integer& operator+(const Integer& i);
 
    //унарный -
    friend const Integer operator-(const Integer& i);
 
    //префиксный инкремент
    friend const Integer& operator++(Integer& i);
 
    //постфиксный инкремент
    friend const Integer operator++(Integer& i, int);
 
    //префиксный декремент
    friend const Integer& operator--(Integer& i);
 
    //постфиксный декремент
    friend const Integer operator--(Integer& i, int);
};
 
//унарный плюс ничего не делает.
const Integer& operator+(const Integer& i) {
    return i.value;
}
 
const Integer operator-(const Integer& i) {
    return Integer(-i.value);
}
 
//префиксная версия возвращает значение после инкремента
const Integer& operator++(Integer& i) {
    i.value++;
    return i;
}
 
//постфиксная версия возвращает значение до инкремента
const Integer operator++(Integer& i, int) {
    Integer oldValue(i.value);
    i.value++;
    return oldValue;
}
 
//префиксная версия возвращает значение после декремента
const Integer& operator--(Integer& i) {
    i.value--;
    return i;
}
 
//постфиксная версия возвращает значение до декремента
const Integer operator--(Integer& i, int) {
    Integer oldValue(i.value);
    i.value--;
    return oldValue;
}
 
class Integer
{
private:
    int value;
public:
    Integer(int i): value(i) 
    {}
    friend const Integer operator+(const Integer& left, const Integer& right);
 
    friend Integer& operator+=(Integer& left, const Integer& right);
 
    friend bool operator==(const Integer& left, const Integer& right);
};
 
const Integer operator+(const Integer& left, const Integer& right) {
    return Integer(left.value + right.value);
}
 
Integer& operator+=(Integer& left, const Integer& right) {
    left.value += right.value;
    return left;
}
 
bool operator==(const Integer& left, const Integer& right) {
    return left.value == right.value;
}
 
[url]http://habrahabr.ru/post/132014/[/url]


Со всеми ли моментами вы согласны? Просто у меня много сомнений. Например, зачем использовать при перегрузке постфиксного и префиксного инкремента\декремента в аргументе объект класса. Ведь прекрасно перегружается и без него. Может стоит делать логические операторы свободными?

Вообщем хочется делать всё как лучше и искренне надеюсь, что не получится как всегда.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.09.2013, 01:31
Ответы с готовыми решениями:

Что лучше всего читать/смотреть где лучше всего практиковаться и как в принципе лучше всего учиться программированию
Здравствуйте,извините за вопрос не по теме но: уже около пол года изучаю С языки и начал понимать что я упустил некоторые моменты,не...

Как правильно перегружать операторы?
Добрый день. Более-менее освоил Си, и вроде бы неплохо в нем разбираюсь. Решил взяться за плюсы. Помогите разобраться с перегрузкой...

Как лучше сделать? LINQ или всё-таки foreach
Добрый день! Как лучше организовать передачу списка List<ObjectInfo> в другую форму (как передать в конструкторе список я знаю), но имеется...

10
интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
08.09.2013, 02:06
friend использовать - считается плохим стилем разработки программного продукта. Они должны появиться в проекте через год, два - от безисходности.
1
 Аватар для gore-lykovoe
32 / 32 / 3
Регистрация: 04.04.2010
Сообщений: 414
08.09.2013, 02:09  [ТС]
Цитата Сообщение от xtorne21st Посмотреть сообщение
friend использовать - считается плохим стилем разработки программного продукта. Они должны появиться в проекте через год, два - от безисходности.
Вы наверное говорите о классах. А я об операторах.
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
08.09.2013, 02:27
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Стоит ли при перегрузке бинарного оператора "+" делать его обособленным от класса?
стоит.
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Нужно ли использовать friend там, где это возможно?
нет.

если перегруженный оператор меняет состояние объекта для которого он вызывается - перегружаем его как мембер, если не меняет - как свободную функцию.
правильная перегрузка оператора + не меняет состояние объектов для которых вызывается, потому её лучше делать независимой.
правильная перегрузка оператора += меняет состояние объекта для которого вызывается, потому её лучше сделать мембером класса.
1
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
08.09.2013, 03:00
Солтер Н.А., Клепер С.Дж. С++ для профессионалов.
Миниатюры
Как же все-таки лучше всего перегружать операторы?   Как же все-таки лучше всего перегружать операторы?   Как же все-таки лучше всего перегружать операторы?  

2
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
08.09.2013, 07:33
Ну, основную причину, по которой используются дружественные перегруженные операторы никто так и не назвал. А она проста – это неявное преобразование типов аргументов. Например, если бы в шаблоне std::complex перегруженный оператор сложения был бы функцией-членом, мы не смогли бы прибавить к действительному числу комплексное.
2
 Аватар для gore-lykovoe
32 / 32 / 3
Регистрация: 04.04.2010
Сообщений: 414
08.09.2013, 11:32  [ТС]
А стоит ли добавлять inline к перегрузкам?
0
188 / 187 / 46
Регистрация: 24.03.2011
Сообщений: 670
08.09.2013, 12:23
Я искренне не понимаю, почему инкремент и декремент сделаны дружественными, а не функциями класса. Никакого профита от этого не вижу, да и текста больше, чем могло бы быть...
0
интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
08.09.2013, 13:20
Цитата Сообщение от monolit Посмотреть сообщение
Я искренне не понимаю, почему инкремент и декремент сделаны дружественными, а не функциями класса. Никакого профита от этого не вижу, да и текста больше, чем могло бы быть...
Для того, чтобы не захламльть класс вспомогательными функциями, без которых, по сути можно и обойтись. Класс должен включать в себя минимильный для функционирования набор методов. Так и код в дальнейшем читать легче и модифицировать класс. Если всёже хотите как-то выделить ваш класс и прилагающие к нему функции/операторы, на фоне другого кода, можно просто обвернуть "это всё дело" в неимспейсы.
0
 Аватар для gore-lykovoe
32 / 32 / 3
Регистрация: 04.04.2010
Сообщений: 414
08.09.2013, 14:25  [ТС]
Цитата Сообщение от xtorne21st Посмотреть сообщение
Для того, чтобы не захламльть класс вспомогательными функциями, без которых, по сути можно и обойтись.
так эти функции и не нужны
плюс, как уже сказали:
Цитата Сообщение от Jupiter Посмотреть сообщение
если перегруженный оператор меняет состояние объекта для которого он вызывается - перегружаем его как мембер
а префиксный инкремент и декрмент как-раз изменяют состояние объекта, да и скрины из книги показывают, что friend не нужен, я лучше доверюсь своему чутью, книгам, опытным пользователям этого форума, чем какому-то учителю, написавшему статью на хабре, где никто не имеет своего мнения, лишь бы им не слили карму...

Добавлено через 15 минут
Побыстрому написал перегрузки, чтобы запомнить, всё ли правильно? Или что-нибудь лучше сделать по-другому?
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>
class Integer
{
    int p;
public:
    int get(void) { return p; }
    void add(int pp) { p+=pp; }
    Integer(int pp) { p=pp; }
    // перегрузка операторов
    Integer(const Integer&);
    // унарные операторы
    Integer& operator= (const Integer&);
    const Integer operator+ () const;
    const Integer operator- () const;
    Integer& operator+= (const Integer&);
    Integer& operator-= (const Integer&);
    Integer& operator++ ();
    const Integer operator++ (int);
    Integer& operator-- ();
    const Integer operator-- (int);
    // операторы ввода/вывода
    friend std::ostream &operator<< (std::ostream&, const Integer&);
    friend std::istream &operator>> (std::istream&, Integer&);
    // операторы сравнения
    friend bool operator == (const Integer&, const Integer&);
    friend bool operator < (const Integer&, const Integer&);
};
// перегрузка копирующего конструктора
Integer::Integer(const Integer& obj)
{
    p=obj.p;
}
// перегрузка присваивания
Integer& Integer::operator= (const Integer& obj)
{
    if (this != &obj)
        p=obj.p;
    return *this;
}
// перегрузка унарного +
const Integer Integer::operator+ () const
{
    return Integer(p);
}
// перегрузка унарного -
const Integer Integer::operator- () const
{
    return Integer(-p);
}
// перегрузка арифметического присваивания +=
Integer& Integer::operator+= (const Integer& obj)
{
    p+= obj.p;
    return *this;
}
// перегрузка арифметического присваивания -=
Integer& Integer::operator-= (const Integer& obj)
{
    p-= obj.p;
    return *this;
}
// перегрузка префиксного инкремента
Integer& Integer::operator++ ()
{
    p++;
    return *this;
}
// перегрузка постфиксного инкремента
const Integer Integer::operator++ (int)
{
    return Integer(++p);
}
// перегрузка префиксного декремента
Integer& Integer::operator-- ()
{
    p--;
    return *this;
}
// перегрузка постфиксного декремента
const Integer Integer::operator-- (int)
{
    return Integer(--p);
}
 
// БИНАРНЫЕ ОПЕРАТОРЫ
// перегрузка сложения
Integer operator+ (const Integer left, const Integer right)
{
    Integer rez(left);
    rez+=right;
    return rez;
}
// перегрузка вычетания
Integer operator- (const Integer left, const Integer right)
{
    Integer rez(left);
    rez-=right;
    return rez;
}
// перегрузка ввода/вывода
std::ostream &operator<< (std::ostream& out, const Integer& obj)
{
    out<<obj.p;
    return out;
}
std::istream &operator>> (std::istream& in, Integer& obj)
{
    in>>obj.p;
    return in;
}
// перегрузка логических операторов
bool operator == (const Integer& obj1, const Integer& obj2)
{
    return (obj1.p==obj2.p);
}
bool operator < (const Integer& obj1, const Integer& obj2)
{
    return (obj1.p<obj2.p);
}
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
08.09.2013, 14:38
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
const Integer operator+ () const;
const Integer operator- () const;
глобальные

перепутал, это унарные, пардон

Цитата Сообщение от gore-lykovoe Посмотреть сообщение
friend bool operator == (const Integer&, const Integer&);
friend bool operator < (const Integer&, const Integer&);
зачем тут friend? у тебя есть метод get(). оператор вывода аналогично, а если добавить ещё метод set то и оператор ввода.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.09.2013, 14:38
Помогаю со студенческими работами здесь

И что же все-таки лучше?
Сейчас у меня phpbb3, в целом все устраивает, но не нравится установка модулей, возникают иногда проблемы, ну и вообще..а дле меня...

Цифровик, что же всё таки лучше.
Здравствуйте, помогите выбрать цифровик стоимостью до 6000 т. руб. Вот ссылка на магазин КЕЙ, с уже отсортированным списком по цене до...

Зачем перегружать операторы в C++?
Зачем перегружать операторы?Я понимаю для того, чтобы можно было делать операции как и со встроенными типами, но вот здесь: class...

Как лучше всего пробежать все элементы контейнера?
Речь о следующем. Есть vector. Я хочу пробежать все его элементы, но походу я буду проверять удовлетворяют они определенному условию или...

Какой выбрать Firewall или родной всё-таки лучше?
Стоит ли от &quot;добра - добра&quot; искать?


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru