| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > действительно константная ссылка |
| Автор: _hunter 7.4.2005, 22:10 |
| Добрый день. Можно ли сделать/объявить действительно константную ссылку? т.е. я сейчас делаю так: const std::vector<int>& SomeFunction(); и, соответственно: const std::vector<int>& data = SomeFunction(); но компилятор пропускает data.clear(); этого можно как-то избежать? Заранее благодарю за ответ. |
| Автор: Fire-Plug 7.4.2005, 22:36 | ||
| Спецификатор const в обьявлении обьекта(переменной, ссылки, указателя) указывает компилятору, что изменять состояние обьекта нельзя (т.е. его следует рассматривать как read-only) Если вектор действительно нужно очистить, ссылку следует обьявить как
|
| Автор: Fire-Plug 7.4.2005, 23:56 | ||
О, блин, сорри - показалось "компилятор НЕ пропускает...." Надо думать... |
| Автор: chipset 8.4.2005, 00:59 |
| А если ссылку на константный обьект попробовать? |
| Автор: Fire-Plug 8.4.2005, 02:11 | ||
| Каким компилятором ты пользуешься? VC6 и выше вызов clear() для констатной ссылки на объект не пропускает, сообщая при этом, что не может конвертнуть this-указатель констатного объекта в неконстантный
|
| Автор: srd 8.4.2005, 02:14 | ||||
| Ты где то ошибся. Пытаюсь скомпилировать следующий код:
Получаю ошибку:
Так что константная ссылка действительно константна. |
| Автор: DENNN 8.4.2005, 09:28 | ||
ИМХО, вопрос реализации и версии STL. На других платформах может быть иначе. |
| Автор: chipset 8.4.2005, 09:43 |
| _hunter, а ты случаем Borland'овский компилер юзаешь? Я слышал, у него бывают заскоки по фазе... Вообще я согласен с DENNN'ом |
| Автор: DENNN 8.4.2005, 10:47 | ||
ССылка то константна, но вот получить по этой ссылке доступ к методам класса ты можешь - > нет никакой гарантии что вызванный метод не изменит свои внутренние данные. |
| Автор: chipset 8.4.2005, 10:54 | ||
Если я не ошибаюсь, методу константного обьекта класса передается константный this и компилер плюется при попытке изменить данные. |
| Автор: srd 8.4.2005, 10:59 | ||||
Для константного объекта данные-члены доступны только на чтение, а из функций-членов доступны только опять-таки константные (т.е. определённые с модификатором const) и статические. Из константных методов менять можно только статические поля и поля со спецификатором mutable, а из статических методов - только статические поля. Так-что гарантия есть.
Не может. Если реализация STL соответствует стандарту, то в ней метод clear() вектора не имеет модификатора const, а значит этот метод не может быть вызван для константных объектов. |
| Автор: np9mi7 8.4.2005, 14:54 | ||
стандарт языка с++ (наверное любой номер) говорит о том, что
А зачем возвращать const ссылку если пользователь твоей функции её только смотрит? Может имеет смысл вернуть копию объекта? Или это экономия памяти? |
| Автор: chipset 8.4.2005, 15:01 | ||
Я ж и говорю, билдерь наверное.. Сейчас придет _Хантер и расскажет |
| Автор: _hunter 8.4.2005, 15:30 | ||
| сорри что так поздно пришел... действительно пишу под билдером ( если это его прикол -- обидно np9mi7, не столько памяти сколько времени ( у меня этих чтений -- туева хуча ) полный код ( чтобы не было вопросов ):
и единственное, что мне на это говорит компилятор: [C++ Warning] W8037 Non-const function _STL::vector<int,_STL::allocator<int> >::clear() called for const object и все |
| Автор: chipset 8.4.2005, 15:35 |
| Значит билдерь пропускает константные вызовы, из еррора превращая их в ворнинги. |
| Автор: _hunter 8.4.2005, 15:54 |
| ясно... (и обидно |
| Автор: np9mi7 8.4.2005, 16:39 |
| ну, так не меняй его? и warnings не будет! ну как вы не понимаете, Builder с++ это чтоб на форму кнопки кидать, на нем мего надежных приложений не пишут! там и vcl только для этого.... |
| Автор: _hunter 8.4.2005, 16:42 |
| я и не меняю. и проблема не в наличии предупрежедения при попытке изменения, а в отсутствии ошибки. |
| Автор: chipset 8.4.2005, 16:51 |
| Если хочешь - можешь попробовать обернуть вектор в враппер запрещающий использовать изменяющие функции, хотя это конечно жуткий гемморой.. |
| Автор: np9mi7 8.4.2005, 16:59 | ||
Или ты в комманде, ну так на уровне бумаги напиши (если руководитель) что так писать нельзя. У меня есть такой документ: Стилистические соглашения, в которых я все такие вещи обговариваю, потом все члены комманды крепят напротив себя это липучкой и все... |
| Автор: chipset 8.4.2005, 17:00 |
| А ещё есть такая фича как "warning as error". |
| Автор: _hunter 8.4.2005, 17:39 |
| так это только у меня будет... а если я из модуля отдаю вектор в твердой уверенности что с ним ничего не сделают. а он пустым оказывается... ( это, пока, все на уровне теорий, но всеравно неприятно... ) |
| Автор: np9mi7 8.4.2005, 17:53 |
| Ну, при определении интерфейса к классу вообще плохой стиль давать внутренность! Возвращай копию и все! |
| Автор: _hunter 8.4.2005, 18:02 |
| да знаю, что плохой стиль, но тут уже проблема скорости появляется ( я выше писал ) |
| Автор: np9mi7 8.4.2005, 18:07 |
| Давай считать. Сколько примерно объектов в контейнере Какие операции хочешь совершать Подожди, какая проблема скорости? Че долго откопировать один контейнер в другой? Те беж нужно его только смотреть, тогда время будет тратиться только на копирование!!! Количество операций с сылкой или копией не измениться! Нет разве? Или я чего не понимаю? |
| Автор: chipset 8.4.2005, 18:10 |
| _hunter, хм, а с защищеными кучами или отображениями файла поиграть если? |
| Автор: _hunter 8.4.2005, 18:14 |
| примерно 3600. да тех классов еще под сотню ( это пока все в планах -- тестирование ведется на 100 первых и 2-х вторых ) + проблема в том, что к первым классам доступ случайным будет ( т.е. получить вначале все копии не получится ) |
| Автор: chipset 8.4.2005, 18:16 | ||
Когда он передаст ссылку - скопируется 32 бита, когда скопирует массив - скопируется дофига_всего. Добавлено @ 18:17 _hunter, ну раз много классов - выделяй из кучи - ставь READ_ONLY. |
| Автор: _hunter 8.4.2005, 18:20 |
| а что за защищенные кучи? с файлами не получится -- нужно подумать... но, чувствую, структуру классов кардинально переделывать придется... |
| Автор: np9mi7 8.4.2005, 18:25 | ||||
это понятно, но количество операций которые он совершит с константной ссылкой после передачи не чуть не больше чем с копией. Разница только на этапе копирования.
или ты хочешь сказать что тебе нужна ссылка на объект который должен меняться, а ты хочешь его постоянно смотреть по этой ссылке |
| Автор: chipset 8.4.2005, 18:27 |
| С отображенными файлами вроде точно такое можно сделать.. Про кучи, только что глянул, что-то очень сомнительная HeapLock да и то от других процессов.. Будем дальше думать. |
| Автор: chipset 8.4.2005, 18:40 |
| http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/creating_named_shared_memory.asp показан пример использования отображения как разделяемой памяти. |
| Автор: Fire-Plug 10.4.2005, 08:37 | ||||||
Нехорошо это, внутренние переменные нетривиального содержания из класса наружу отдавать. Это же не совсем аналогично ситуации вида: size_t someclass:size() const; А как же инкапсуляция? Ежели какому-то классу-клиенту этот вектор нужен для принципиальных целей, то это должен быть его атрибут. И он будет передавать его по ссылке методу класса-хэлпера, к-рый знает, например, как этот вектор заполнить (ну, скажем, прочти чего-то из конфигурации, посчитай, найди и т.д. и т.п и положи в этот вектор). Если предложенная модель не годится, то иногда удобнее сдублировать часть интерфейса вектора в его классе-контейнере. Например,
Добавлено @ 08:41
Во, блин, как плохо читать постинги через один! chipset уже эту идею предложил... |