Название: Константность Отправлено: Igors от Сентябрь 21, 2012, 11:30 Добрый день
Слышал что const_cast - это плохо, очень плохо, явный дефект в архитектуре и.т.п. Всем понятно что чем меньше приведений типов - тем лучше, однако иногда я не вижу способа их избежать. Вот напр такая ситуация Код Само тело FindItem вызывает только др константные методы, все гуд. А вот с возвращенным указателем (на данные класса) сложнее. В большинстве случаев он const, но иногда необходимо менять данные по этому указателю. Заметим что код метода значителен (не какой-нибудь однострочный оператор), и повторять его 2 раза (с конст и без) никак не хорошо. Как Вы решаете такую ситуацию? Спасибо Название: Re: Константность Отправлено: QtCoder от Сентябрь 21, 2012, 11:46 Раз иногда надо менять, то значит он никакой не const.
Тогда просто MyItem * FindItem() const; Название: Re: Константность Отправлено: Igors от Сентябрь 21, 2012, 12:10 Раз иногда надо менять, то значит он никакой не const. Так не могу вернуть - MyItem указывает на данные класса Тогда просто MyItem * FindItem() const; Название: Re: Константность Отправлено: Akon от Сентябрь 21, 2012, 12:46 Igors:
То, что вы привели - есть const propagation (распространиение константности), когда имея конст. ссылку мы можем получить только конст. на другие объекты. В противоположность этому Код: MyItem * FindItem() const; Кроме как локального и абсолютно контролируемого программистом снятия константности, никакое другое разумное использование const_cast мне в голову не приходит. Название: Re: Константность Отправлено: Igors от Сентябрь 21, 2012, 12:51 Кроме как локального и абсолютно контролируемого программистом снятия константности, никакое другое разумное использование const_cast мне в голову не приходит. Так понял что const_cast здесь неизбежно. Согласен с этим. А с Название: Re: Константность Отправлено: LisandreL от Сентябрь 21, 2012, 14:54 Слышал что const_cast - это плохо, очень плохо, явный дефект в архитектуре и.т.п. Я писал «почти наверняка», так что не совсем «явный», некоторую долю сомнения я оставил. :DЗаметим что код метода значителен (не какой-нибудь однострочный оператор), и повторять его 2 раза (с конст и без) никак не хорошо. Соглашусь. Повторять 2 раза плохо прежде всего из-за того, что потом меняя код можно в одном месте можно забыть изменить его в другом.Как Вы решаете такую ситуацию? Зависит от ситуации. Где возможно делаю геттеры и сеттеры. Но не при любом MyItem такой подход удобен/применим.Кроме как локального и абсолютно контролируемого программистом снятия константности, никакое другое разумное использование const_cast мне в голову не приходит. Ну да, как-то так получается. В своём коде и чётко понимая что делаешь.Хуже ситуация, когда нечто такое было бы удобно с чужим кодом/библиотекой. Мы ведь умные, можем посмотреть, как там всё устроено и что снятием константности мы ничего не сломаем. А потом берём следующую версию библиотеки и программный интерфейс там тот же, а код - другой, и наш «хак» приводит к самым непредвиденным последствиям. И в принципе тоже возможно и с собственным кодом при изменениях, если забудем, что где-то снимали константность. В общем я придерживаюсь правил при использовании const_cast: со сторонним кодом не использовать, в полностью своём кодом обходиться как с сильнодействующим лекарством: применять если «ожидаемая польза превышает потенциальный риск». Не претендую на истинность в последней инстанции. P.S. Недавно использовал Speex. Кодирование фрейма: Код Входной буффер неконстаным указателем?! Вроде бы по логике не должен он изменяться внутри, но вдруг… И что мне локальную копию делать? Хм… Что интересно в API предлагаемого теперь на замену Opus'а такого огреха нет: Код
Название: Re: Константность Отправлено: DmitryM от Сентябрь 21, 2012, 15:51 Слышал что const_cast - это плохо, очень плохо, явный дефект в архитектуре и.т.п. Всем понятно что чем меньше приведений типов - тем лучше, однако иногда я не вижу способа их избежать. Вот напр такая ситуация Менять содержимое объекта класса MyItem, не оповещая объект класса MyClass, не хорошо с точки зрения ООП. Код Само тело FindItem вызывает только др константные методы, все гуд. А вот с возвращенным указателем (на данные класса) сложнее. В большинстве случаев он const, но иногда необходимо менять данные по этому указателю. Заметим что код метода значителен (не какой-нибудь однострочный оператор), и повторять его 2 раза (с конст и без) никак не хорошо. Спасибо Название: Re: Константность Отправлено: andrew.k от Сентябрь 21, 2012, 18:39 Igors: Вообще там такого метода нет.То, что вы привели - есть const propagation (распространиение константности), когда имея конст. ссылку мы можем получить только конст. на другие объекты. В противоположность этому Код: MyItem * FindItem() const; В примера константный метод возвращает константный указатель, а неконстантный соответственно неконст. Так что все по-честному. А по теме. Я думаю, приведенный пример это не очень удачное проектирование. Сама по себе операция поиск она константная (чисто логически), поэтому метод findItem() должен быть только const. И видимо должен возвращать что-то типа индекса, для доступа к данным в этом классе. А уже имея индекс мы должны иметь возможность получить оба варианта указателя. Второй момент вызывая неконстантный findItem я не могу быть уверен(если не я писал этот класс конечно), что объект сохранится неизменным, даже если я не стану менять полученный элемент. Может там есть какой-нибудь счетчик доступа или еще что-нибудь, какие-нибудь механизмы включаются. А с volatille не лучше выходит? (не пробовал) А с volatile мне кажется не получится либо получится полная ерунда (это если volatile ставить на сами данные).Что можно попробовать это сохранять внутри класса этот самый индекс, о котором я выше писал. А уже из самих функций findItem вызывать соответствующий метод getItem или getConstItem получая нужный указатель. Но чем такие игры лучше чем, const_cast я не вижу. Название: Re: Константность Отправлено: Igors от Сентябрь 21, 2012, 19:00 Не то чтобы эта ситуация очень частая, но и какой-то редкой/экзотической ее не назовешь. Возвращение указателя на константу нужно по понятным причинам, напр для пользования классом извне. С др стороны вот я делаю какую-то содержательную работу - возможно методом того же MyClass. Да, изменяю объект - не скрываю, так что, мне FindItem не использовать? Приходится рисовать как-то так
Код Есть лучшие предложения? Название: Re: Константность Отправлено: andrew.k от Сентябрь 21, 2012, 19:03 То что я описал про volatile примерно так. Может как-то украсить можно, убрать дублирование. Но я лишь идею с volatile показать хотел.
Код
Название: Re: Константность Отправлено: DmitryM от Сентябрь 21, 2012, 19:58 Если бы я писал библиотеку и столкнулся бы с такой ситуацией, то возвращал бы не ссылку на объект, а прокси объект.
Никого же не удивляет стандартный begin() Код
Название: Re: Константность Отправлено: Igors от Сентябрь 21, 2012, 20:15 Но я лишь идею с volatile показать хотел. Код
Цитировать - Поручик, но зачем же они яйца закапывают? :) Чего ж Вы volatile к индексу прилепили? Здесь он никакого отношения к константности не имеет. - Дикари-с Вариант с индексом понятен, но требует ощутимых переделок. Напр я вставляю новые элементы в тот же QList, адрес элемента у меня неизменный, а вот индекс "уплывает". Индекс может быть сложен (напр для дерева) да и не уверен в большом счастье обладания индексом - да, компилятору рот закрыли, но теперь самому решать когда же он валиден. Если бы я писал библиотеку и столкнулся бы с такой ситуацией, то возвращал бы не ссылку на объект, а прокси объект. Называется "сменял шило на мыло", теперь какой итератор вернуть - константный или нетНикого же не удивляет стандартный begin() Код
Название: Re: Константность Отправлено: andrew.k от Сентябрь 21, 2012, 23:09 Чего ж Вы volatile к индексу прилепили? Здесь он никакого отношения к константности не имеет. Да. поторопился. Я хотел сохранять найденный индекс в index_, поэтому поставил volatile.Но это даже не пригодилось. Название: Re: Константность Отправлено: andrew.k от Сентябрь 21, 2012, 23:43 Вся соль в том, чтобы отделить мухи от котлет: сам механизм поиска (сложный метод, который должен быть константным) и возврат указывающей сущности (указель, ссылка или итератор) - это пару строк, тут видимо будет дублирование кода (как в моем примере).
И я не понял насчет уплывания индекса. Ну и пусть уплывает. Этот индекс предназначен для внутреннего использования и актуален только на момент поиска. Можно методы getA сделать приватными. Пользователь класса все равно в результате получает искомый указатель "требуемой константности" :) Боже. Вот меня заглючило. Говоря volatile я имел в виду mutable. :) Название: Re: Константность Отправлено: andrew.k от Сентябрь 22, 2012, 00:08 А вот вообще без заморочек:
Код ;) Название: Re: Константность Отправлено: DmitryM от Сентябрь 22, 2012, 09:33 Называется "сменял шило на мыло", теперь какой итератор вернуть - константный или нет Учи мат. часть. Возвращаемое значение функции, не является частью сигнатурой функции, поэтому так писать не правильноКод
Однако шаблоны предоставляют выбор, какое значение получать Код
Название: Re: Константность Отправлено: Igors от Сентябрь 22, 2012, 11:32 Боже. Вот меня заглючило. Говоря volatile я имел в виду mutable. :) Я тоже перепутал в посте #4 :) Исправил. Вроде mutable и предназначен для таких целей, но я не знаю как "вернуть mutable указатель". А завести mutable член, перелить сначала в него и затем вернуть можно, но не яснее и даже не корочеНазвание: Re: Константность Отправлено: DmitryM от Сентябрь 22, 2012, 20:39 :рукалицо:
Igors, andrew.k если вы себя называете C++ программистами, то ответьте на вопрос, вызов какого FindItem должен поставить компилятор? Код: class MyClass { Название: Re: Константность Отправлено: andrew.k от Сентябрь 23, 2012, 01:54 :рукалицо: Тут будет вызов неконстантной версии, т.к. функция mail?? (ты я так понимаю, нас не считаешь за программстов, но себя да : ) не имеет спецификатора const.Igors, andrew.k если вы себя называете C++ программистами, то ответьте на вопрос, вызов какого FindItem должен поставить компилятор? Код: class MyClass { Но к чему этот вопрос? Рукалицо это ты удачно подметил. Насчет первого примера, я торопился написал ерунду, не проверил даже. Я написал это выше. Есть претензии ко второму примеру? Название: Re: Константность Отправлено: Igors от Сентябрь 23, 2012, 06:02 Насчет первого примера, я торопился написал ерунду, не проверил даже. Я написал это выше. Если искать решение самому, то ошибки неизбежны, и это нормально. А вот отвечать, на мой взгляд, не всякому следует. "если вы считаете себя", "учи матчасть" - борзости с избытком. А доходит до дела - тупо лепит книжку и даже не в тему. Ну и зачем вступать с ним в бесполезные пререкания?Есть претензии ко второму примеру? |