Здравствуйте, Аноним, Вы писали:
Т.е. вот так вот делать можно:
А>А> class A
А> {
А> mutable int i;
А> public:
А> A():i(10)
А> {
А> }
А> void foo()
А> {
А> i = 10;
А> }
А> };
А> const A a;
А> (const_cast<A *>(&a))->foo();
А>
Вообще-то можно и без const_cast...
А> class A
{
mutable int i;
public:
A():i(10)
{
}
void foo() const
{
i = 100;
}
};
const A a;
a.foo();
Но в том, что попытка изменить какое-нибудь данное стандартного типа с нативной константностью -- UB.
Но, ИМХО, это не главное. Главное понимать зачем вообще нужно использовать спецификатор const
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
E>Но в том, что попытка изменить какое-нибудь данное стандартного типа с нативной константностью -- UB.
E>Но, ИМХО, это не главное. Главное понимать зачем вообще нужно использовать спецификатор const ![](/Forum/Images/smile.gif)
Это так конечно. Но проблема в том что у новичков бытует мнение что "раз работает — значит можно" и это надо рубить на корню. Вон топик стартер даже говорит что раз работает что значит или VC неправилен или документация. Таким людям надо просто и ясно объяснить всю "прелесть" понятия UB. А философскими соображениями красивости кода и правильности архитектуры переубедить людей которые думают на уровне 1000 строчек кода сложно.
Здравствуйте, Кодт, Вы писали:
К>К>>> ::SystemTimeToVariantTime( // :: (SYSTEMTIME*,DATE*)->BOOL, каззлы
К>>> (SYSTEMTIME*)&st, // или *const_cast<SYSTEMTIME&>(st)
К>>> &dt
К>>> );
К>
К>Тогда я не понял вопроса. Ты просил код, где C-style-cast нужен — вот он, пожалуйста. Из-за кривого объявления апишной функции.
Дело в том, что если попытаться использовать С — style cast для вышеописанной задачи (код в первом сообщении ветки, то есть привести константную ссылку(указатель) к неконстантному), то возвращается указатель (ссылка) на приведенную к нужному типу копию обьекта, а не на сам приводимый обьект. Так что остается только const_cast.
К>Если у объекта есть mutable член, то компилятор запихнёт его в секцию данных. После чего защита не сработает. Ну, поломаешь логику программы.
Забавно то, что она (защита) не работает вообще, хотя казалось бы должна. (код в первом сообщении ветки)
Здравствуйте, dandy, Вы писали:
D>Дело в том, что если попытаться использовать С — style cast для вышеописанной задачи (код в первом сообщении ветки, то есть привести константную ссылку(указатель) к неконстантному), то возвращается указатель (ссылка) на приведенную к нужному типу копию обьекта, а не на сам приводимый обьект. Так что остается только const_cast.
Это если написать
A& ref = (A)a;//a имеет тип const A&
А если вот так:
A& ref = (A&)a;
A& ref = *(A*)&a;
то получим ссылку на оригинальный объект.
Кстати вариант
A& ref = (A)a тоже нелегален с точки зрения стандарта, т.к. для инициализации неконстантной ссылки используется r-value (за подробностями можно обратиться в поиск).
К>>Если у объекта есть mutable член, то компилятор запихнёт его в секцию данных. После чего защита не сработает. Ну, поломаешь логику программы.
D>Забавно то, что она (защита) не работает вообще, хотя казалось бы должна. (код в первом сообщении ветки)
Да никто тут никому ничего не должен. Стандарт не обещает никаких защит. Все, что он обещает — это неопределенное поведение при попытке модификации "настоящей" константы. Все. Как это неопределенное поведение себя проявит — никто не знает.