![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
AXELman4ever |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 31 Регистрация: 22.9.2011 Пользователь №: 2902 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Всем добрый!
Пытаюсь понять принцип работы const_cast. Для интереса про-инициализировал значение (int) переменной в стеке, вместо того, чтобы создать на него указатель. После чего, загнал ссылку переменной и решил привести к типу pointer на int, дабы снять с переменной константность: const int i = 5; int *ptr = const_cast <int*> (&i); после чего решил инкрементировать значение по указателю и проверить, изменилось ли значение константной переменной. Для уверенности и сравнения обеих значений вызвал адрес на который ссылается указатель, и адрес ссылки. И вот чему я был удивлен. Адрес, который хранит указатель и адрес ссылки - одинаковы, но значения у них разные: qDebug() << "*ptr: "<< ptr << "-" << *ptr; // *ptr: 0x28ff10 - 6 qDebug() << "&i: "<< &i << "-" << i; // &i : 0x28ff10 - 5 Объясните пожалуйста, как так происходит? и почему const_cast нельзя вызвать для константных типов значений? PS: Посоветуйте какую-нибудь легкодоступную для понимая книжечку по азам С++, если можно. Книги читать не люблю, но, так понимаю, без них никак. Заранее благодарен. |
|
|
Алексей1153 |
![]()
Сообщение
#2
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
мдя, что курим ?
![]()
или
но лучше так не делать. Константа должна оставаться константой ещё лучше применть енум
тогда таких вопросов точно не возникнет Сообщение отредактировал Алексей1153 - 24.9.2011, 10:03 |
|
|
BRE |
![]()
Сообщение
#3
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Влад |
![]()
Сообщение
#4
|
Участник ![]() ![]() Группа: Участник Сообщений: 146 Регистрация: 20.3.2009 Из: Санкт-Петербург Пользователь №: 627 Спасибо сказали: 46 раз(а) Репутация: ![]() ![]() ![]() |
Компилятор GCC 4.5
|
|
|
Гость_D_* |
![]()
Сообщение
#5
|
Гости ![]() |
Компилятор GCC 4.5
Здесь происходит Access Violation по той причине, что константа у вас находится в статической области памяти. В этом случае измнять ее не получится, поскольку она помещается в специального рода память. |
|
|
Гость_D_* |
![]()
Сообщение
#6
|
Гости ![]() |
Вот вам ответ, почему так происходит
Код:
А вот что мы увидем если компилировать его в ассемблерный код. Это только фрагмены:
По русски это означает, что срабатывает оптимизация зависящая от реализации конкретного компилятора. Поскольку на этапе компиляции, здесь значение const i уже известно, компилятор при выводе его значения сразу подставляет число 5. При этом в ассемблерном коде видно, что при инкременте значение i действительно изменяется. У Страуструпа написано, что подобного рода приведения создают ситуации в результате которых поведение константных объектов становится неопределенным А еще, например, можно сделать так:
Тогда все будет уорректно. Поскольку значение константы на этапе компиляции здесь не известно. Лёгких книжек по С++ не ищите. В плане понимания... мне очень нравится Философия С++ Брюса Эккеля. Совсем для начала можно Липпмана... у Эккеля в начале много абстрактного и исторического, поэтому может быть скучно. Но он хорош, он оперирует к размышлениям о языке, о его конструкциях и концепциях... кроме того у него большой опыт в преподавании С++. Со Страуструпа сразу начинать я бы не советовал, но прочесть тоже нужно. |
|
|
Iron Bug |
![]()
Сообщение
#7
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Алексей1153 |
![]()
Сообщение
#8
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
Цитата Так же как и пользоваться сишным приведением в C++. я не суеверный Цитата // Хе-хе. Как бы не так! Здесь реально происходит Access Violation что вполне ожидаемо, особенно в релизе. Ибо не трогай константу ![]() Сообщение отредактировал Алексей1153 - 24.9.2011, 15:59 |
|
|
AXELman4ever |
![]()
Сообщение
#9
|
Студент ![]() Группа: Участник Сообщений: 31 Регистрация: 22.9.2011 Пользователь №: 2902 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
В очередной раз благодарю всех отписавшихся. За 1 день обитания на форуме узнаю больше чем за 1 год обитания в ВУЗе
![]() |
|
|
![]() ![]() ![]() |
![]() |
Текстовая версия | Сейчас: 17.2.2025, 3:58 |