![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Rapalex |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 732 Регистрация: 20.1.2006 Где: Украина -> Ник олаев Репутация: нет Всего: 8 |
У одного класса есть 2 функции:
Разница между ними только в том что одна из них константная. Когда это функции в одну строчку типа:
я спокоен, а как в таком случае можно избавится от дублирования кода? Это сообщение отредактировал(а) Rapalex - 10.8.2007, 12:02 -------------------- In vitium ducit culpae fuga. Желание избежать ошибки вовлекает в другую. (Horatius) |
||||
|
|||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
если есть возможность сделать ф-ю константной, то неконстантная обычно не нужна, так как константная будет работать и для неконстантных аргументов.
Короче константная канает везде а обычная не везде. Это сообщение отредактировал(а) Lazin - 10.8.2007, 12:10 |
|||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Написать еще одну
PS Целесобразность присутствия в классе двух таких функций оставляем вне рамок данного обсуждения -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
Вообще нужно либо делать ф-ии константными везде где это можно, либо вообще их не использовать, но в этом случае константными объектами будет проблематично пользоваться.
|
|||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
В данном случае, насколько я понял, константность функции нужна, что бы иметь перeгрузку функций, формально отличающихся только возращаемым типом
По стандарту такая перегрузка невозможи и для того чтобы это обойти, одна из фукций объявлена константной. Благо, код функции позволяет воспользоваться такой возможностью При этом имеею смелость предположить, что автор топика несколько заблуждается по поводу того, в каких случаях будет вызываться та или иная функция -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| Rapalex |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 732 Регистрация: 20.1.2006 Где: Украина -> Ник олаев Репутация: нет Всего: 8 |
Vyacheslav, константная функция будут вызыватся если я работаю с константным указателем, а если указатель не константный, то вызовется не константная функция.
А с делано это для того чтобы при работе с константным обектом его функция вернула константный указатель, тем самым не допустив изменения данных, иными словами спасает меня от потенциальных ошибок. Это сообщение отредактировал(а) Rapalex - 10.8.2007, 14:55 -------------------- In vitium ducit culpae fuga. Желание избежать ошибки вовлекает в другую. (Horatius) |
|||
|
||||
| Vyacheslav |
|
||||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Вот это в данной формулировке не совсем корректно
Все таки не с константным указателем, а константным объектом. При этом не важно посредством чего к нему обращаются: посредством указателя, ссылки или используют сам объект. Я к тому, что в случае
вызовется неконстантный вариант
А вот это , скажем так, понятно но не черезчур Вы себя контролируете? Константный или неконстантный объект - это уже известно на этапе компиляции, если объект константный а функции констатной нет, то Вы сами можете написать
И фиг Вам дальше компилятор позволят изменить pGsr Единственное отличие, что в случае наличия константной функции Вас компилятор обругает, если Вы случайно ошибетесь и напишите
Ради одного этого такой огород городить? Неужели не в состоянии сами себя проконтролировать. Все таки это не тот случай, когда в аналогичном случае в STL возвращается iterator и const_iterator ( const_iterator != const iterator Единственная польза от такого приема в конкретном случае мне видится только одна: если Вы любитель "многоуровневых" обращений
-------------------- С уважением, Вячеслав Ермолаев |
||||||||||||
|
|||||||||||||
| Ln78 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
Хороший вопрос. Я сам раньше дублировал, сейчас попробовал несколько изменённый пример
Vyacheslavа, получилось (по крайней мере в VS2005):
ИМХО, часто стоит: например, для контейнеров, у которых перегружаются операторы [] для доступа к элементам это бывает очень полезно Да, кстати, Rapalex, для соседнего топика: например, в книге Элджера варианты константных указателей и указателей на константу расписаны Это сообщение отредактировал(а) Ln78 - 10.8.2007, 16:03 |
|||
|
||||
| Vyacheslav |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
ЭЭЭ. Нельзя же разумную идею превращать в ее противоположность. Если бы это был оператор[], то я бы не имел ничего против, поскольку для оператор [] естественно использование типа
т. е. обращение через временную ссылку, константность которой можно задать только заранее Тут довольно легко ошибиться, причем на автомате -------------------- С уважением, Вячеслав Ермолаев |
||||
|
|||||
| Ln78 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
Я имел в виду: основная идея - избежать дублирования фукнций (и операторов в том числе), а уж к чему её применить, это уже другой вопрос
|
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
Vyacheslav, как я понимаю, это требуется (и у меня нередко требовалось) в случае, если нужно:
1) CGsr* GetGsr(const CSourceType *poSourceType); Получать указатель на внутренние данные с целью их изменения. (некрасиво, т.е. не по ООП'ному, но иногда важна именно скорость). 2) const CGsr*GetGsr(const CSourceType *poSourceType) const; Получать указатель на внутренние данные с целью их "чтения" в других константных функциях. Ну, и еще можно не добавлять 3ю функцию, а вызвать в неконстантной константную через ((const CProject*) this)->... Но это дело вкуса, как я понимаю.... Если я не прав, просьба не нервничать. Это сообщение отредактировал(а) Alek86 - 10.8.2007, 22:31 |
|||
|
||||
| Rapalex |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 732 Регистрация: 20.1.2006 Где: Украина -> Ник олаев Репутация: нет Всего: 8 |
Ln78,
А можно полне название книги, чтоб погуглить смог Alek86, полность согласен, особенно с
-------------------- In vitium ducit culpae fuga. Желание избежать ошибки вовлекает в другую. (Horatius) |
||||
|
|||||
| Ln78 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
Rapalex, книга из серии "Библиотека программиста", автор Джеф Элджер, название "С++". У меня только бумажная версия.
И кстати, почему согласен только с Alek86? В моём примере как раз это и приведено, так же, как и отсутствие промежуточной функции. |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
Ln78, в твоем примере
константная функция вызывает неконстантную? |
|||
|
||||
| Ln78 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
Alek86, а сам как думаешь? Скопируй пример, дополни вызовом функции F и посмотри под отладчиком, кто что вызывает. Ну а сколько в моём примере функций вроде и так видно. Чтобы не повышать мелкодисперсность оксида двухатомного водорода механическим путём (воду в ступе толочь) вряд ли нужно обсуждать это ещё на несколько постов.
|
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
проверил, работает...
странно, я всегда считал, что внутри константных функций неконстантные вызывать нельзя... добавлено: понял уже. хитрый прием, не знал. теперь тему можно закрывать Это сообщение отредактировал(а) Alek86 - 11.8.2007, 16:13 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
Вообще компилятор и сам умеет за этим следить, поэтому он будет сильно против, если попытаться получить неконстантный указатель на данные константного объекта. То-есть нельзя возвращать обычный указатель на данные объекта из константной ф-ии. Так-же не получится вызвать неконстантную ф-ю для константного объекта, так-что всё логично, без перегрузки не обойтись, по другому не получится сделать, если конечно нужно создавать константные объекты. |
|||
|
||||
| Rapalex |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 732 Регистрация: 20.1.2006 Где: Украина -> Ник олаев Репутация: нет Всего: 8 |
Всем спасибо.
-------------------- In vitium ducit culpae fuga. Желание избежать ошибки вовлекает в другую. (Horatius) |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
|
|||
|
||||
| d06osipov |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 1.11.2006 Репутация: нет Всего: нет |
Зато так вы не сможете избежать ошибок в самой процедуре. Если вы используете const_cast информация о константности теряется и компилятор уже не может проследить, чтобы ваша функция не модифицировала класс.
Насколько я знаю, во всех известных мне реализациях STL применяется именно дублирование кода, хотя это становится порядочной занозой в одном месте, которая может быть разрешится в следующей версии Стандарта. Я бы на вашем месте не использовал const_cast без необходимости. Лучше всего, мне кажется дублирование кода, но если очень не хочется, можно обратится к препроцессору, например так:
И использовать это так:
хотя тут тоже уйма недостатков |
||||
|
|||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
да уж
прошел чуть ли не год и я тоже уже думаю, что лучше мелкий копипаст вот так вот меняются взгляды... ) |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
||||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Достаточно выражать неконстантную функцию через константную, и таких ошибок не будет.
Мсье знает толк в извращениях. При юзании твоего макроса как минимум появится проблема с использованием запятых в теле функции. Это сообщение отредактировал(а) UnrealMan - 24.5.2008, 12:10 |
|||
|
||||
| JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Если константная функция вернёт мне const T, то мне ничего не остаётся, как сделать const_cast<T&>(...), чтобы вернуть то, что должна возвратить неконстантная функция. Другое дело, что это как раз очень безобидное применение const_cast. |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
||||
|
||||
| korian |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 651 Регистрация: 8.3.2008 Где: Украина, Харьков Репутация: 3 Всего: 17 |
интересует мнение по поводу такой реализации const / не const геттеров, чтобы избежать дублирования кода.
(мнения тех, кто считает std::vector ошибкой проектирования не интересуют)
Это сообщение отредактировал(а) korian - 20.3.2009, 13:18 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| korian |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 651 Регистрация: 8.3.2008 Где: Украина, Харьков Репутация: 3 Всего: 17 |
ну
вопрос какой извращение лучше |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| korian |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 651 Регистрация: 8.3.2008 Где: Украина, Харьков Репутация: 3 Всего: 17 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ага вместо объяснения лучше покажу примером :
а в общем лучше обходится без таких извращений. Если есть расчеты, то их надо вынести в независимую функцию, а в остальном (якобы) копипаст не так страшен Это сообщение отредактировал(а) mes - 20.3.2009, 20:43 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |