| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > 2 вида функций const и обычная. |
| Автор: Rapalex 10.8.2007, 12:00 | ||||
У одного класса есть 2 функции:
Разница между ними только в том что одна из них константная. Когда это функции в одну строчку типа:
я спокоен, а как в таком случае можно избавится от дублирования кода? |
| Автор: Lazin 10.8.2007, 12:09 |
| если есть возможность сделать ф-ю константной, то неконстантная обычно не нужна, так как константная будет работать и для неконстантных аргументов. Короче константная канает везде а обычная не везде. |
| Автор: Vyacheslav 10.8.2007, 12:54 | ||
Написать еще одну
PS Целесобразность присутствия в классе двух таких функций оставляем вне рамок данного обсуждения |
| Автор: Lazin 10.8.2007, 13:25 |
| Вообще нужно либо делать ф-ии константными везде где это можно, либо вообще их не использовать, но в этом случае константными объектами будет проблематично пользоваться. |
| Автор: Vyacheslav 10.8.2007, 14:15 | ||
В данном случае, насколько я понял, константность функции нужна, что бы иметь перeгрузку функций, формально отличающихся только возращаемым типом
По стандарту такая перегрузка невозможи и для того чтобы это обойти, одна из фукций объявлена константной. Благо, код функции позволяет воспользоваться такой возможностью При этом имеею смелость предположить, что автор топика несколько заблуждается по поводу того, в каких случаях будет вызываться та или иная функция |
| Автор: Rapalex 10.8.2007, 14:54 |
| Vyacheslav, константная функция будут вызыватся если я работаю с константным указателем, а если указатель не константный, то вызовется не константная функция. А с делано это для того чтобы при работе с константным обектом его функция вернула константный указатель, тем самым не допустив изменения данных, иными словами спасает меня от потенциальных ошибок. |
| Автор: Ln78 10.8.2007, 16:00 | ||
| Хороший вопрос. Я сам раньше дублировал, сейчас попробовал несколько изменённый пример Vyacheslavа, получилось (по крайней мере в VS2005):
ИМХО, часто стоит: например, для контейнеров, у которых перегружаются операторы [] для доступа к элементам это бывает очень полезно Да, кстати, Rapalex, для соседнего топика: например, в книге Элджера варианты константных указателей и указателей на константу расписаны |
| Автор: Vyacheslav 10.8.2007, 16:14 | ||||
ЭЭЭ. Нельзя же разумную идею превращать в ее противоположность. Если бы это был оператор[], то я бы не имел ничего против, поскольку для оператор [] естественно использование типа
т. е. обращение через временную ссылку, константность которой можно задать только заранее Тут довольно легко ошибиться, причем на автомате |
| Автор: Ln78 10.8.2007, 16:23 |
| Я имел в виду: основная идея - избежать дублирования фукнций (и операторов в том числе), а уж к чему её применить, это уже другой вопрос |
| Автор: Alek86 10.8.2007, 17:43 |
| Vyacheslav, как я понимаю, это требуется (и у меня нередко требовалось) в случае, если нужно: 1) CGsr* GetGsr(const CSourceType *poSourceType); Получать указатель на внутренние данные с целью их изменения. (некрасиво, т.е. не по ООП'ному, но иногда важна именно скорость). 2) const CGsr*GetGsr(const CSourceType *poSourceType) const; Получать указатель на внутренние данные с целью их "чтения" в других константных функциях. Ну, и еще можно не добавлять 3ю функцию, а вызвать в неконстантной константную через ((const CProject*) this)->... Но это дело вкуса, как я понимаю.... Если я не прав, просьба не нервничать. |
| Автор: Rapalex 11.8.2007, 09:45 | ||||
Ln78,
А можно полне название книги, чтоб погуглить смог Alek86, полность согласен, особенно с
|
| Автор: Ln78 11.8.2007, 11:33 |
| Rapalex, книга из серии "Библиотека программиста", автор Джеф Элджер, название "С++". У меня только бумажная версия. И кстати, почему согласен только с Alek86? В моём примере как раз это и приведено, так же, как и отсутствие промежуточной функции. |
| Автор: Alek86 11.8.2007, 11:50 | ||
Ln78, в твоем примере
константная функция вызывает неконстантную? |
| Автор: Ln78 11.8.2007, 14:53 |
| Alek86, а сам как думаешь? Скопируй пример, дополни вызовом функции F и посмотри под отладчиком, кто что вызывает. Ну а сколько в моём примере функций вроде и так видно. Чтобы не повышать мелкодисперсность оксида двухатомного водорода механическим путём (воду в ступе толочь) вряд ли нужно обсуждать это ещё на несколько постов. |
| Автор: Alek86 11.8.2007, 15:59 |
| проверил, работает... странно, я всегда считал, что внутри константных функций неконстантные вызывать нельзя... добавлено: понял уже. хитрый прием, не знал. теперь тему можно закрывать |
| Автор: Lazin 11.8.2007, 20:32 | ||
Вообще компилятор и сам умеет за этим следить, поэтому он будет сильно против, если попытаться получить неконстантный указатель на данные константного объекта. То-есть нельзя возвращать обычный указатель на данные объекта из константной ф-ии. Так-же не получится вызвать неконстантную ф-ю для константного объекта, так-что всё логично, без перегрузки не обойтись, по другому не получится сделать, если конечно нужно создавать константные объекты. |
| Автор: Rapalex 23.5.2008, 13:15 |
| Всем спасибо. |
| Автор: Alek86 23.5.2008, 16:32 |
| |
| Автор: d06osipov 23.5.2008, 18:43 | ||||
| Зато так вы не сможете избежать ошибок в самой процедуре. Если вы используете const_cast информация о константности теряется и компилятор уже не может проследить, чтобы ваша функция не модифицировала класс. Насколько я знаю, во всех известных мне реализациях STL применяется именно дублирование кода, хотя это становится порядочной занозой в одном месте, которая может быть разрешится в следующей версии Стандарта. Я бы на вашем месте не использовал const_cast без необходимости. Лучше всего, мне кажется дублирование кода, но если очень не хочется, можно обратится к препроцессору, например так:
И использовать это так:
хотя тут тоже уйма недостатков |
| Автор: Alek86 23.5.2008, 19:18 |
| да уж прошел чуть ли не год и я тоже уже думаю, что лучше мелкий копипаст вот так вот меняются взгляды... ) |
| Автор: vinter 23.5.2008, 22:32 | ||
сколько людей, столько мнений. Я считаю что макросы - зло. |
| Автор: UnrealMan 24.5.2008, 12:08 | ||||
Достаточно выражать неконстантную функцию через константную, и таких ошибок не будет.
Мсье знает толк в извращениях. При юзании твоего макроса как минимум появится проблема с использованием запятых в теле функции. |
| Автор: JackYF 25.5.2008, 01:02 | ||
Если константная функция вернёт мне const T, то мне ничего не остаётся, как сделать const_cast<T&>(...), чтобы вернуть то, что должна возвратить неконстантная функция. Другое дело, что это как раз очень безобидное применение const_cast. |
| Автор: UnrealMan 25.5.2008, 01:47 |
Дык об этом и речь. Некоторые люди очень любят катить совершенно пустые бочки на const_cast, reinterpret_cast, макросы и т.д. |
| Автор: korian 20.3.2009, 13:16 | ||
| интересует мнение по поводу такой реализации const / не const геттеров, чтобы избежать дублирования кода. (мнения тех, кто считает std::vector ошибкой проектирования не интересуют)
|
| Автор: mes 20.3.2009, 14:19 | ||
имхо извращение |
| Автор: korian 20.3.2009, 14:28 | ||
ну
вопрос какой извращение лучше |
| Автор: mes 20.3.2009, 15:20 | ||||
имхо с const_cast, только в обратном виде, чем в цитате. |
| Автор: korian 20.3.2009, 19:53 | ||
в обратном виде - это так?
а чем так лучше? |
| Автор: mes 20.3.2009, 20:39 | ||
ага вместо объяснения лучше покажу примером :
а в общем лучше обходится без таких извращений. Если есть расчеты, то их надо вынести в независимую функцию, а в остальном (якобы) копипаст не так страшен |