Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> вопросы к операции const_cast 
:(
    Опции темы
novice2011
Дата 16.2.2012, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 23.7.2011

Репутация: нет
Всего: нет



Код

#include<iostream>
using namespace std;

class Low
{
private:
     int hold;
public:
    Low(const int h = 0) : hold(h) {}
    virtual void show() const {cout << "hold " << hold << endl;}    
};

class High : public Low
{
private:
    double boom;
public:
    explicit High(double db = 0, int h = 0) : boom(db), Low(h) {}
    virtual void show() const { Low::show(); cout << "boom " << boom << endl; }    
};

int main()
{    
    const int b = 2;
    const int & x = b;
    int c = const_cast<int &>(x);
    c = 3;
    cout << c << ' ' << x << ' ' << b << endl; // с = 3; x и b = 2;    
    const High bar(77.7, 7);
    bar.show();    
    High *dar;
    dar = const_cast<High*>(&bar);
    *dar = High(999.9, 222);        
    dar->show();    
    bar.show();    
    return 0;
}
     

Переменная b объявлена с идентификатором const, поэтому операция  const_cast не может изменить ее значение. Объект bar так же объявлен с идентификатором const, однако операция  const_cast меняет его значение. Вопрос, почему? По идее, не должна.
PM MAIL   Вверх
boostcoder
Дата 16.2.2012, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



Цитата(novice2011 @  16.2.2012,  09:00 Найти цитируемый пост)
поэтому операция  const_cast не может изменить ее значение. 

не по этому. у тебя ошибка в коде.

найди десять отличий ;) : http://liveworkspace.org/code/2a4c89cc868d...04b0059b7543f6e

Добавлено через 1 минуту и 20 секунд
Цитата(novice2011 @  16.2.2012,  09:00 Найти цитируемый пост)
поэтому операция  const_cast не может изменить ее значение

и если бы он не мог - ты бы получил ошибку компиляции.

Добавлено через 1 минуту и 46 секунд
с ссылками все по взрослому smile 
PM WWW   Вверх
novice2011
Дата 16.2.2012, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 23.7.2011

Репутация: нет
Всего: нет



Цитата(boostcoder @ 16.2.2012,  09:17)
у тебя ошибка в коде.



Уважаемый, boostcoder, ввиду своей неопытности я не понял, а где именно ошибка в коде? Не смогли бы вы пояснить?
PM MAIL   Вверх
mes
Дата 16.2.2012, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(novice2011 @  16.2.2012,  09:59 Найти цитируемый пост)
 а где именно ошибка в коде? Н

одна тут :
Цитата(novice2011 @  16.2.2012,  08:00 Найти цитируемый пост)
 int c = const_cast<int &>(x);

int& c =...



--------------------
PM MAIL WWW   Вверх
novice2011
Дата 16.2.2012, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 23.7.2011

Репутация: нет
Всего: нет



Цитата(mes @ 16.2.2012,  11:08)
int& c =...

Да, вы правы, но после исправления этой ошибки все остается по-прежнему.
PM MAIL   Вверх
mes
Дата 16.2.2012, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(novice2011 @  16.2.2012,  10:18 Найти цитируемый пост)
 но после исправления этой ошибки все остается по-прежнему. 

все ли ?  с этой ошибкой не происходило изменения значения, а сейчас происходит, даже если вывод этого не показывает  smile
вообщем если у вас выводится старое значение, то  это не чудеса  smile, а проделки компилятора  smile
вот это поможет поправить вывод :
Код

    volatile const int b = 2;
    volatile const int & x = b;
    int& c = const_cast<int &>(x);



--------------------
PM MAIL WWW   Вверх
novice2011
Дата 16.2.2012, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 23.7.2011

Репутация: нет
Всего: нет



Да, но в этом коде дело даже не в переменной с.  Просматривая литературу, я прочитал: "Операция const_cast не во всем хороша. Она может изменить указатель на величину, но эффект от изменения значения, заданного как const, не определен". В этом же коде объект bar объявляется как const, но тем не менее, с помощью операции const_cast его можно изменить, что противоречит выше приведенной цитате из книги Стивена Прата. Вот этого я и не пойму.

PM MAIL   Вверх
xvr
Дата 16.2.2012, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(novice2011 @  16.2.2012,  12:12 Найти цитируемый пост)
что противоречит выше приведенной цитате

Не противоречит. 'не определен' это не значит 'не меняется', это значит 'может быть что угодно', т.е. может и поменяться, а может и нет

PM MAIL   Вверх
mes
Дата 16.2.2012, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(novice2011 @  16.2.2012,  11:12 Найти цитируемый пост)
его можно изменить, что противоречит 

 а чем противоречит ?! 



--------------------
PM MAIL WWW   Вверх
novice2011
Дата 16.2.2012, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 23.7.2011

Репутация: нет
Всего: нет



Понял, всем большое спасибо!
PM MAIL   Вверх
mes
Дата 16.2.2012, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



novice2011,  для полноты понимания, нужно учитывать что бывает три вида констант:
1. реальныя константа рантайма, находящаяся  в read-only памяти - менять такую  никогда нельзя 
например char *str = "hello";  из за совместимости можно присвоить реальный константный объект неконстантной переменной, но изменение ее чревато исключением.. 

2. логическая константа - обычная переменная помеченная квалификатором const - такие менять с помощью const_cast относительно  безопасно, за исключением проявления шуток оптимизатора, как у вас в примере..

3. константное выражение - это константа времени компиляции и не неаходится в памяти.. 
так например выражение  
 const int size = 4; 
создает одну константную переменную,которую можно изменить и ассоциированное с ним константное выражение, которое можно применять например при создании массивов
 int arr[size];
при этом размер массива будет равен первоначальному значению, даже если вы до этого изменили size через конст_каст.. 

smile



--------------------
PM MAIL WWW   Вверх
novice2011
Дата 16.2.2012, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 23.7.2011

Репутация: нет
Всего: нет



Да, поясню, что вопросы у меня возникли после этого примера:


Код

#include <iostream>
using std::cout;
using std::endl;

void change(const int * pt, int n);

int main()
{
    int pop1 = 38383;
    const int pop2 = 2000;
    
    cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl;
    change(&pop1, -1);
    change(&pop2, -1);
    cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl;

    return 0;
}

void change(const int * pt, int n)
{
    int * pc;
    if (n < 0)
    {
        pc = const_cast<int *>(pt);
        *pc = 100;
    }
}


Вывод программы: pop1, pop2: 38383, 2000
pop1, pop2: 100, 2000
Т.е здесь pop2 не изменяется, поэтому я и попробовал применить const к объекту класса. Но объект класса в результате поменял свое значение, в отличие от pop2 в этом примере.
PM MAIL   Вверх
mes
Дата 16.2.2012, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(novice2011 @  16.2.2012,  11:45 Найти цитируемый пост)
Т.е здесь pop2 не изменяется

опять та же ошибка в понимании..  "не изменяется" и "выводится старое значение" это разное поведение smile

можно вот так заставить компилятор выводить актуальное значение константы :
Код

    cout << "pop1, pop2: " << pop1 << ", " <<  const_cast<int&>(pop2) << endl;



Это сообщение отредактировал(а) mes - 16.2.2012, 13:25


--------------------
PM MAIL WWW   Вверх
novice2011
Дата 16.2.2012, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 23.7.2011

Репутация: нет
Всего: нет



Спасибо, mes.
PM MAIL   Вверх
boostcoder
Дата 17.2.2012, 04:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



Цитата(novice2011 @  16.2.2012,  11:18 Найти цитируемый пост)
после исправления этой ошибки все остается по-прежнему. 

Цитата(mes @  16.2.2012,  11:45 Найти цитируемый пост)
с этой ошибкой не происходило изменения значения, а сейчас происходит, даже если вывод этого не показывает

зачем вы гадаете? ссылку-то я на что дал?
PM WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0633 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.