![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| iff |
|
||||
![]() Администратор ![]() ![]() Профиль Группа: Участник Сообщений: 949 Регистрация: 23.3.2007 Репутация: нет Всего: 16 |
Когда нужно использовать ссылки а когда нет?
A - это класс
при это -= написан так:
может быть если возвращаемый результат ссылка (в примере с -=), то новый объект удаляется и возвращается ссыка на старый, но изменённый (return *this)? при этом если возвращать ссылку в операторе -, то возникает предупреждение что она указывает на локальную переменную (там создаётся др. объект) -------------------- DOS... Синей пеленой экран заполнил чистый DOS Мышь... Стала вдруг квадратной, потеряла форму мышь... Я разбил окно, девяностопятое мастдайное окно, И поставил DOS, и тогда увидел: Это счастье, — вот оно. |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
Лучше делать наоборот. написать только оператор -=, а оператор - выражать через него.
Вот как у вас написано, так и нужно. (только первый, это унарный минус. он немножко здесь не к месту.) |
||||
|
|||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Лучше наверно так:
Это сообщение отредактировал(а) math64 - 13.5.2013, 09:44 |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
math64, тогда уж substract д.б. static
Это сообщение отредактировал(а) borisbn - 13.5.2013, 10:35 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| baldina |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
да и так, и так нормально. разница вкусовая (естественно, в обоих случаях можно обойтись без friend и статических функций)
Добавлено через 1 минуту и 52 секунды кстати, см. boost::operators, там так и сделано |
||||
|
|||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
не совсем вкусовая. оператор-= более естествен, и его можно написать с меньшим оверхедом. здесь создание лишнего временного экземпляра, лишний оператор присваивания, и лишнее удаление временного экземпляра. |
|||
|
||||
| baldina |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
согласен, и мне так больше нравится. но таки это вкусовой вопрос))
vs
при использовании дадут практически идентичный код Добавлено @ 14:09 тут скорее разница в том, что в случае
может не получится неявного преобразования, требуются ужимки и прыжки Скажем,
поэтому лучше предпочитать Foo::operator+=(const Foo&); Это сообщение отредактировал(а) baldina - 13.5.2013, 16:37 |
||||||||
|
|||||||||
| NoviceF |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Насколько я понимаю, в первом варианте очепятка
Но, если верить Саттеру, 1й вариант это всётаки каноническая форма http://programming-lang.com/ru/comp_progra...tter/0/j55.html |
||||
|
|||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
||||
|
||||
| baldina |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
перечитал по ссылке, вижу что
1. под канонической формой он понимает взаимосвязь (в т.ч. связанное определение) operator оп() и operator оп=(). у нас это подразумевается и выполняется в обоих случаях 2. имеется упоминание неявных преобразований, о которых я упоминал
3. как вариант приводится и вторая форма
и
В общем я принципиальных отличий от своего поста не вижу. Думаю, еще надо учесть, что писалось это 10лет назад, с тех пор оптимизаторы несколько ушли вперед (например хорошо научились делать NRVO), и некоторые соображения эффективности уже не играют существенной роли. Тем не менее форма с operator@= членом класса и свободной функцией operator@, реализованной через первый оператор, мне импонирует больше, т.к. позволяет меньше думать о преобразованиях и эффективности, поэтому, если не используются boost::operators, ей следует отдавать предпочтение. Не забывая, что этот вариант не является единственно правильным)) |
||||||
|
|||||||
| NoviceF |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Так я о принципиальных отличиях и не писал "В общем случае для некоторого бинарного оператора @ (+, -, * и т.д.) вы должны также определить его присваивающую версию, так чтобы a@=b и a=a@b имели один и тот же смысл (причем первая версия может быть более эффективна). Канонический способ достижения данной цели состоит в определении @ посредством @= следующим образом:.." |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
baldina, в общем случае не дадут идентичный код. я уже писал, там создание лишнего объекта, лишний оператор присваивания. Возможности оптимизатора не безграничны. и он далеко не для всех типов может удалить конструктор, оператор присваивания и деструктор. А для сложных типов, эти функции могут быть достаточно ресурсоемки. Оператор+= можно написать, в большинстве случаев без создания временной переменной. если же мы его выражаем через оператор+, то без создания временной переменной не обойтись. Это сообщение отредактировал(а) volatile - 13.5.2013, 19:58 |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Господа опытные программисты, когда вы в последний раз переопределяли операторы -=() и/или -() в боевом проекте? Что это был за класс? Я, наверное, недостаточно опытный, т.к. не могу вспомнить, когда мне это было необходимо.
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Я это делал, когда писал с++ обертку для bigdigits.
В принципе, переопределение данного операторов (да и всех математических) имеет смысл только для матемаических классов. |
|||
|
||||
| baldina |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
не так часто, конечно)) обычно алгебра, bsa прав из последних - классы математических выражений для отображения хода вычислений, года три назад. давно как-то приходилось вектора/матрицы писать Добавлено через 6 минут и 44 секунды еще (довольно давно) были классы для вычислений с учетом размерностей иногда возникают небольшие задачи с использованием operator+ специального вида для строк (вроде конкатенации с добавлением разделителя) Добавлено через 10 минут и 21 секунду пара
по идее должны давать одинаковый код при любой реализации. конечно, это от самих классов и компилятора зависит... давайте проведем эксперимент: предлагайте (разумную) семантику operator+() в конкретном, гипотетически полезном случае - сравним |
||||
|
|||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Обычно, оператор + реализуется через +=:
|
|||
|
||||
| volatile |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
Ну хорошо. Давайте, чтоб не скучно было, выведем первую тыщу чисел фибоначчи. Код конечно далёк от оптимального, (например. в чаре храницца только число в диапазоне [0..9], ну да суть не в этом.
Будем подсчитывать кол-во созданных объектов big_num, потребовавшихся для вычисления. в первом варианте (BALDINA_VARINT) сорри за имя 'BALDINA_VARINT', что-то ничего больше не пришло больше в голову. переименуйте как вам угодно.
На gcc и в студии одинаково. В студии была максимальная оптимизация на скорость + Use Link Time Code Generation Добавлено через 7 минут и 6 секунд Попробовал на codepad.org. Тыщу чисел он не смог переварить, уменьшил в 10 раз http://codepad.org/02MJuOJS http://codepad.org/Ol4LplTE objects: 202 objects: 102 но там без оптимизации. На домашнем компе objects: 102 objects: 52 В любом случае разница в 2 раза количества объектов сохраняецца. |
||||||||
|
|||||||||
| baldina |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
да, все верно
пример мог быть и попроще, если деструкторами измерять, доп объект всегда присутствует. кстати, вариант со свободной функцией operator+(), некоторыми компиляторами оптимизируется хуже, чем с членом класса. интересно, что (в данном конкретном случае), компилятор таки умудряется обходиться без фактического "лишнего копирования":
здесь от временного объекта только один след - изменение деструктором object_counter сравните с явно определенным operator=()
Это сообщение отредактировал(а) baldina - 15.5.2013, 14:05 |
||||
|
|||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
|
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
кол-во деструкторов == равно кол-ву констукторов == кол-ву объектов. деструкторами измерялось только в силу удобства определения в одном месте. Хорошо, хотя это не совсем корректно по сравнению с кол-вом объектов. Тем не менее, операторов присваивания, как и деструкторов в 2 раза больше:
Это сообщение отредактировал(а) volatile - 15.5.2013, 18:52 |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Кстати, оператор присваивания рекомендуется делать через операцию swap.
|
|||
|
||||
| volatile |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
bsa, чтоб делать через swap, нужно сначала написать этот swap И кстати, даже если решицца писать его, то для данного конкретного класса, swap априори будет менее эффективен чем memcpy. Так что слепо следовать рекомендациям, далеко не всегда оправдано.
baldina, в общем как я понял, вы хотите сказать, что не смотря на разницу в количестве объектов, операторов присваивания, деструкторов и прочих сишних прибамбасов, компилятор, каким-то неведомым, волшебным способом делает так, что код, всё равно выполняецца за одинаковое время... Ну чтож, давайте (чтоб уже добить тему) измерим и время... Время в миллионах тиков процессора. (по 3 измерения на каждый вариант) Первый вариант
Второй вариант
Весь проект для 2008-ой студии (без бинарников). Это сообщение отредактировал(а) volatile - 15.5.2013, 23:53 Присоединённый файл ( Кол-во скачиваний: 2 )
operators.7z 3,98 Kb |
||||||
|
|||||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Да. Не обратил внимания. Обычно, такое через динамические массивы делают.
|
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Доберусь до компа, погляжу.
Да, я имел в виду что в частных случаях (частых для математических классов) результат может быть одинаков за счет оптимизации. В общем конечно нет, если требуется вызывать сложные конструкторы/деструкторы Как уже говорил, я сам за каноническую форму, просто хотелось побудить к размышлению и расставить все точки. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |