X>cannot convert from 'class TBase ** ' to 'const class TBase ** '
class TBase
{
TBase() : a(0) {}
int a;
};
//....
TBase const a;
TBase b;
TBase * pa = &a;
TBase const * pb = &b;
TBase const ** ppb = &pb;
// пока все ок
ppb = &pa;
*ppb = pb; // теперь pa указывает на b (эквивалентно pa = pb)
pa->a = 2; // меняем константные данные
На самом деле до "пока все ок" не дойдёт. Сломается ещё на TBase * pa = &a;
Здравствуйте, Smal, Вы писали:
S>
S>class TBase
S>{
S> TBase() : a(0) {}
S> int a;
S>};
S>//....
S>TBase const a;
S>TBase b;
S>TBase * pa = &a;
S>TBase const * pb = &b;
S>TBase const ** ppb = &pb;
S>// пока все ок
S>
Re[2]: почему так нельзя делать?
От:
Аноним
Дата:
29.07.08 08:26
Оценка:
Здравствуйте, _Paul, Вы писали: _P>Здравствуйте, xray2000, Вы писали: X>>cannot convert from 'class TBase ** ' to 'const class TBase ** ' _P>Запрещено стандартом, см. пункт 4.4.4 _P>Пример на простых типах, который демонстрирует к чему это может привести: _P>
_P> int a1;
_P> int *a2 = &a1;
_P> const int **a3 = &a2;
_P> const int c = 1;
_P> *a3 = &c;
_P> *a2 = 2; // Oops! Пытаемся менять константу с.
_P>
На сторке
const int **a3 = &a2;
error C2440: 'initializing' : cannot convert from 'int **__w64 ' to 'const int **'
Re[2]: почему так нельзя делать?
От:
Аноним
Дата:
29.07.08 08:33
Оценка:
Здравствуйте, Smal, Вы писали:
S>Здравствуйте, xray2000, Вы писали: X>>cannot convert from 'class TBase ** ' to 'const class TBase ** ' S>
S>class TBase
S>{
S> TBase() : a(0) {}
S> int a;
S>};
S>//....
S>TBase const a;
S>TBase b;
S>TBase * pa = &a;
S>TBase const * pb = &b;
S>TBase const ** ppb = &pb;
S>// пока все ок
S>ppb = &pa;
S>*ppb = pb; // теперь pa указывает на b (эквивалентно pa = pb)
pa->>a = 2; // меняем константные данные
S>
После добавления pablic: в class TBase
На строке
TBase * pa = &a;
error C2440: 'initializing' : cannot convert from 'const TBase *__w64 ' to 'TBase *'
На строке
ppb = &pa;
error C2440: '=' : cannot convert from 'TBase **__w64 ' to 'const TBase **'
Так вы поро что собственно говорите...похоже о том чего и так не может быть
Здравствуйте, Аноним, Вы писали:
А>Так вы поро что собственно говорите...похоже о том чего и так не может быть
Так это и был пример неоднозначного поведения кода если бы было разрешено неявно
приводить двойной указатель к константности. Догоняйте...
Re[4]: почему так нельзя делать?
От:
Аноним
Дата:
29.07.08 09:13
Оценка:
Здравствуйте, leonty, Вы писали:
L> Догоняйте...
Ну это догнал...
int a1;
int *a2 = &a1; //*a2-->a1const int **a3 = &a2; //**a3-->*a2-->a1 //err, но предположим что так можноconst int c = 1;
*a3 = &c; //*a3-->&c; *a2-->a1; //err, но предположим что так можно
*a2 = 2; // Oops! Пытаемся менять константу с.
// почему меняем константу с, вроде только a1, т.к. *a3 = &c;
строка "расцепила" **a3-->*a2-->a1; на *a3-->c; *a2-->a1;
Вазде этот пример вызывает недоумение т.к. ошибочная *a3 = &c; т.е. переустановка **a3
на &c, переустанавливает и *a2 на &c.
Строка (с ошибкой) *a3 = &c; расцепила бы связку **a3-->*a2-->a1 на *a3-->&c; *a2-->a1; и соответственно *a2 = 2; поменяла бы только a1 но никак ни &c
Не понимаю эти "Oops!"
А> *a3 = &c; //*a3-->&c; *a2-->a1; //err, но предположим что так можно
А>Вазде этот пример вызывает недоумение т.к. ошибочная *a3 = &c; т.е. переустановка **a3 А>на &c, переустанавливает и *a2 на &c.
Так разыменовывая а3 мы и получаем доступ к а2 и изменяем его значение.
"*а3" — это не самостоятельная сущность, это алиас для того, на что оно указывает.
т.е. "*а3 = " то же самое, что и "а2 = "
Re[6]: почему так нельзя делать?
От:
Аноним
Дата:
29.07.08 12:19
Оценка:
Здравствуйте, leonty, Вы писали: L>Так разыменовывая а3 мы и получаем доступ к а2 и изменяем его значение. L>"*а3" — это не самостоятельная сущность, это алиас для того, на что оно указывает. L>т.е. "*а3 = " то же самое, что и "а2 = "
Да понял,спасибо.
int i=1;
int *pi=&i;
int const *cpi=pi;
*pi=7;// изменился указатель на константу int const*ci
i=9;
cpi меняется и не споткнуться на int const *ci=pi;
Почему же int const *cpi=pi разрешается int const **a3 = &a2; нет
Здравствуйте, Аноним, Вы писали:
А>Почему же int const *cpi=pi разрешается int const **a3 = &a2; нет
потому что тут нет побочных эффектов. Как не крути, а тип указателя и
данные друг другу соответствуют. А там мы могли создать ситуацию, что
обычный указатель ссылается на константные данные (и может май кар кирдык
сделать при вполне законной попытке их изменения).