почему так нельзя делать?
От: xray2000 Россия  
Дата: 24.07.08 11:34
Оценка:
cannot convert from 'class TBase ** ' to 'const class TBase ** '
Re: почему так нельзя делать?
От: Smal Россия  
Дата: 24.07.08 11:56
Оценка: 7 (4) +1
Здравствуйте, xray2000, Вы писали:


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; // меняем константные данные
С уважением, Александр
Re: почему так нельзя делать?
От: _Paul Россия  
Дата: 24.07.08 12:02
Оценка: 2 (1)
Здравствуйте, xray2000, Вы писали:

X>cannot convert from 'class TBase ** ' to 'const class TBase ** '


Запрещено стандартом, см. пункт 4.4.4

Пример на простых типах, который демонстрирует к чему это может привести:

  int a1;
  int *a2 = &a1;
  const int **a3 = &a2;

  const int c = 1;
  *a3 = &c;
  *a2 = 2; // Oops! Пытаемся менять константу с.


Можешь еще поискать по форуму, этот вопрос уже неоднократно обсуждался.
Re: почему так нельзя делать?
От: Programador  
Дата: 24.07.08 13:48
Оценка: -2
Здравствуйте, xray2000, Вы писали:

X>cannot convert from 'class TBase ** ' to 'const class TBase ** '


Дыу должно быть можно
'const class TBase ** ' to 'class TBase ** ' незя
Re: [:]||||||[:] (-)
От: Roman Odaisky Украина  
Дата: 24.07.08 15:50
Оценка:
До последнего не верил в пирамиду Лебедева.
Re[2]: [:]||||||[:] (-)
От: Programador  
Дата: 24.07.08 16:09
Оценка:
Здравствуйте, Roman Odaisky,
туда нэлязя, сюда нэльзя
Re[2]: почему так нельзя делать?
От: leonty  
Дата: 29.07.08 07:51
Оценка:
На самом деле до "пока все ок" не дойдёт. Сломается ещё на 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[3]: почему так нельзя делать?
От: leonty  
Дата: 29.07.08 08:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Так вы поро что собственно говорите...похоже о том чего и так не может быть


Так это и был пример неоднозначного поведения кода если бы было разрешено неявно
приводить двойной указатель к константности. Догоняйте...
Re[4]: почему так нельзя делать?
От: Аноним  
Дата: 29.07.08 09:13
Оценка:
Здравствуйте, leonty, Вы писали:

L> Догоняйте...


Ну это догнал...

  int a1;
  int *a2 = &a1;         //*a2-->a1
  const 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!"
Re[3]: почему так нельзя делать?
От: Smal Россия  
Дата: 29.07.08 10:06
Оценка:
Здравствуйте, leonty, Вы писали:

L>На самом деле до "пока все ок" не дойдёт. Сломается ещё на TBase * pa = &a;



L>Здравствуйте, 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>>


Прошу прощения. Не туда вставил const.
TBase a;
TBase const b;
С уважением, Александр
Re[5]: почему так нельзя делать?
От: leonty  
Дата: 29.07.08 10:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>  *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; нет
Re[7]: почему так нельзя делать?
От: leonty  
Дата: 29.07.08 12:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Почему же int const *cpi=pi разрешается int const **a3 = &a2; нет


потому что тут нет побочных эффектов. Как не крути, а тип указателя и
данные друг другу соответствуют. А там мы могли создать ситуацию, что
обычный указатель ссылается на константные данные (и может май кар кирдык
сделать при вполне законной попытке их изменения).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.