| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > вопросы к операции const_cast |
| Автор: novice2011 16.2.2012, 09:00 | ||
Переменная b объявлена с идентификатором const, поэтому операция const_cast не может изменить ее значение. Объект bar так же объявлен с идентификатором const, однако операция const_cast меняет его значение. Вопрос, почему? По идее, не должна. |
| Автор: boostcoder 16.2.2012, 09:17 |
не по этому. у тебя ошибка в коде. найди десять отличий ;) : http://liveworkspace.org/code/2a4c89cc868dec36c04b0059b7543f6e Добавлено через 1 минуту и 20 секунд и если бы он не мог - ты бы получил ошибку компиляции. Добавлено через 1 минуту и 46 секунд с ссылками все по взрослому |
| Автор: novice2011 16.2.2012, 10:59 | ||
Уважаемый, boostcoder, ввиду своей неопытности я не понял, а где именно ошибка в коде? Не смогли бы вы пояснить? |
| Автор: mes 16.2.2012, 11:08 |
одна тут : int& c =... |
| Автор: novice2011 16.2.2012, 11:18 | ||
Да, вы правы, но после исправления этой ошибки все остается по-прежнему. |
| Автор: mes 16.2.2012, 11:45 | ||
все ли ? с этой ошибкой не происходило изменения значения, а сейчас происходит, даже если вывод этого не показывает вообщем если у вас выводится старое значение, то это не чудеса вот это поможет поправить вывод :
|
| Автор: novice2011 16.2.2012, 12:12 |
| Да, но в этом коде дело даже не в переменной с. Просматривая литературу, я прочитал: "Операция const_cast не во всем хороша. Она может изменить указатель на величину, но эффект от изменения значения, заданного как const, не определен". В этом же коде объект bar объявляется как const, но тем не менее, с помощью операции const_cast его можно изменить, что противоречит выше приведенной цитате из книги Стивена Прата. Вот этого я и не пойму. |
| Автор: xvr 16.2.2012, 12:24 |
Не противоречит. 'не определен' это не значит 'не меняется', это значит 'может быть что угодно', т.е. может и поменяться, а может и нет |
| Автор: mes 16.2.2012, 12:25 |
а чем противоречит ?! |
| Автор: novice2011 16.2.2012, 12:27 |
| Понял, всем большое спасибо! |
| Автор: mes 16.2.2012, 12:40 |
| novice2011, для полноты понимания, нужно учитывать что бывает три вида констант: 1. реальныя константа рантайма, находящаяся в read-only памяти - менять такую никогда нельзя например char *str = "hello"; из за совместимости можно присвоить реальный константный объект неконстантной переменной, но изменение ее чревато исключением.. 2. логическая константа - обычная переменная помеченная квалификатором const - такие менять с помощью const_cast относительно безопасно, за исключением проявления шуток оптимизатора, как у вас в примере.. 3. константное выражение - это константа времени компиляции и не неаходится в памяти.. так например выражение const int size = 4; создает одну константную переменную,которую можно изменить и ассоциированное с ним константное выражение, которое можно применять например при создании массивов int arr[size]; при этом размер массива будет равен первоначальному значению, даже если вы до этого изменили size через конст_каст.. |
| Автор: novice2011 16.2.2012, 12:45 | ||
Да, поясню, что вопросы у меня возникли после этого примера:
Вывод программы: pop1, pop2: 38383, 2000 pop1, pop2: 100, 2000 Т.е здесь pop2 не изменяется, поэтому я и попробовал применить const к объекту класса. Но объект класса в результате поменял свое значение, в отличие от pop2 в этом примере. |
| Автор: mes 16.2.2012, 13:24 | ||
опять та же ошибка в понимании.. "не изменяется" и "выводится старое значение" это разное поведение можно вот так заставить компилятор выводить актуальное значение константы :
|
| Автор: novice2011 16.2.2012, 15:01 |
| Спасибо, mes. |
| Автор: LeonidPr 17.2.2012, 09:33 | ||||||
Заинтересовала эта тема (особенно в плане проделок компилятора), решил попробовать запустить этот пример с вашими исправлениями. И столкнулся с интересной особенностью компиляторов. После сборки и запуска примера в C++ Builder 5 получил вывод в консоли: 3 3 2 (т.е. в качестве значения b выводится то, что ей присвоили). Компиляция этого примера компилером gcc дала результат: 3 3 3. Возможно необходимо ковырять настройки Builder-а, но оптимизацию я полностью отключил. Решил посмотреть, что-же генерит Builder. Скормил exe-шник ida и получил следующее (комментарии мои):
Получается, как было уже сказано mes, "не изменяется" и "выводится старое значение" это разное поведение. Компилятор при выводе константы запихнул в стек не то значение, которое расположено в памяти, выделенной для этой константы, а то значение, которым её инициализировали при объявлении. |
| Автор: mes 17.2.2012, 09:37 |
гадание это ко мне относится ? ну так я не знаю же результатов именно тс, даже если по ссылке показывает эту ошибку |
| Автор: boostcoder 17.2.2012, 14:08 |
не понял.. т.е. http://liveworkspace.org/code/2a4c89cc868dec36c04b0059b7543f6e результат не верный? Добавлено через 57 секунд ааа, точно странно... |
| Автор: boostcoder 17.2.2012, 14:54 |
| newbee бдит! |
| Автор: novice2011 18.2.2012, 13:31 |
| Да, уж, теперь я точно понял, что совершенно ничего не понял. |
| Автор: bsa 18.2.2012, 14:19 |
| novice2011, а что тут понимать? Язык С++ очень мощный. На нем можно и легкое быстрое приложение состряпать для встраиваемого девайса, а можно и распределенную систему промышленного уровня написать за вменяемые сроки. Но за все надо платить: язык содержит в себе ряд спорных особенностей (иногда даже ошибок проектирования самого языка), которые при неправильном использовании могут сильно усложнить жизнь. Поэтому, чтобы все эти особенности освоить, нужно огромное время изучения и практики. Если ты чувствуешь в себе силы всю жизнь учиться, а так же желание писать программы, то добро пожаловать к нам - С/С++ программистам. Если же тебе хочется только попробовать, то можешь начать с что-нибудь попроще. |
| Автор: novice2011 18.2.2012, 19:56 |
| Спасибо, bsa. Хочется стать таким же грамотным, как ребята, которые помогли мне уяснить некоторые моменты, поэтому остается только утроить свои усилия по изучению языка. |