Ошибки, баги, вопросы - страница 3396

 
Andrey Dik #:
о! пока писал пост - Вы раньше предложили.)
Ваш способ инициализации массива даже удобнее, спасибо!

Это неудобно хотя бы тем, что при таком способе явная (!) ошибка компилятором не обнаруживается:

 C_Ind* inds [] = {((const C_Ind *)new C_AVE1), ((const C_Ind *)new C_AVE2)}; //нормально???

А в Вашем "неудобном" (а на самом деле более правильном) способе компилятор сразу о ней сообщит в случае чего:

inds [0] = ((const C_Ind *)new C_AVE1); //Error: '=' - cannot convert from const pointer to nonconst pointer
inds [1] = ((const C_Ind *)new C_AVE2); //Error: '=' - cannot convert from const pointer to nonconst pointer
 
class A {};

void OnStart()
{
  const A* a1[];
  A* a2[];
  
  ArrayResize(a1, ArrayResize(a2, 1));

  a2[0] = a1[0]; //'=' - cannot convert from const pointer to nonconst pointer
  
  a2[0] = (A*)a1[0]; //OK
  Print(ArraySwap(a2, a1)); // true  
  Print(ArrayCopy(a2, a1)); // 1
}
 
A100 #:

Это неудобно хотя бы тем, что при таком способе явная (!) ошибка компилятором не обнаруживается:

А в Вашем "неудобном" (а на самом деле более правильном) способе компилятор сразу о ней сообщит в случае чего:

Это для меня очень сложно, к сожалению, Вы меня напугали.

Буду разбираться.

Если не трудно, поясните, пожалуйста, в чем может быть проблема при такой инициализации и как она проявится?

 
Andrey Dik #:

Это для меня очень сложно, к сожалению, Вы меня напугали.

Буду разбираться.

Если не трудно, поясните, пожалуйста, в чем может быть проблема при такой инициализации и как она проявится?

Проблема может быть в трудноуловимой ошибке (там где Вы ее и не ожидаете вовсе). Я сообщал ранее Разработчикам об этом, но они длительное время не исправляют, а значит лучше воздержаться от такого способа {} инициализации, благо что есть традиционный, через =

 
fxsaber #:
ArraySwap

Правильно! ArraySwap нужно запретить в принципе, потому что он нарушает константность

 
A100 #:

Проблема может быть в трудноуловимой ошибке (там где Вы ее и не ожидаете вовсе). Я сообщал ранее Разработчикам об этом, но они длительное время не исправляют, а значит лучше воздержаться от такого способа {} инициализации, благо что есть традиционный, через =

Понятно. Жаль, потому что при "=" придется сначала объявлять объекты а потом присваивать массиву, это увеличит код как минимум в два раза (хотя, благо, это нужно сделать всего один раз, а далее просто обращаться к массиву через цикл).
 
A100 #:

Откуда такие сведения?

Достаточно в базовом

Спасибо. Нужно будет проверить. Всегда объявлял в производных тоже виртуальными. Просто потому, что когда-то не сработал вызов метода из производного. Объявил виртуальным и заработало. Могу ошибаться в причине из-за давности описываемых событий (может и сигнатура была иной - не помню уже). Но теперь всегда виртуальные методы делаю во всех классах виртуальными, и проблем не имею.

 
Artyom Trishkin #:

Спасибо. Нужно будет проверить. Всегда объявлял в производных тоже виртуальными. 

Я то же объявляю, но это не обязательно

 
Andrey Dik #:
Понятно. Жаль, потому что при "=" придется сначала объявлять объекты а потом присваивать массиву, это увеличит код как минимум в два раза (хотя, благо, это нужно сделать всего один раз, а далее просто обращаться к массиву через цикл).

Не заморачиваюсь и пишу лаконично. Потенциальная проблема здесь.

class A { public: int i; };

void OnStart()
{
  const A a; // Создан const-объект - запрет на изменение полей, разрешается вызывать только const-методы.
  
  Print(a.i);
  
  ((A*)&a).i = 5; // В const-объекте все равно изменили поле.
  Print(a.i); // 5
  
  ((A)a).i = 7;   // В const-объекте все равно изменили поле.
  Print(a.i); // 7  
}

Неизменяемый объект при желании может меняться, но это нужно явно захотеть, создав определенную конструкцию. Т.е. программист специально что-то делает, понимая, к чему это приведет.

В случае же с массивами конструкцию создавать не нужно, поэтому программист может не понимать, что случайно поменял объект, и теперь объект стал вести себя не так, как планировалось.

Это правильное поведение.
 
Andrey Dik #:
Понятно. Жаль, потому что при "=" придется сначала объявлять объекты а потом присваивать массиву, это увеличит код как минимум в два раза (хотя, благо, это нужно сделать всего один раз, а далее просто обращаться к массиву через цикл).

В данном случае уместна будет запись в строку и нумерация с 0:

C_Ind *inds[2];
C_Ind *ave0 = new C_AVE0(); inds[0] = ave0;
C_Ind *ave1 = new C_AVE1(); inds[1] = ave1;
Причина обращения: