Classes and class hierarchies
C.152
Никогда не присваивайте указатель на массив объектов производного класса указателю на его базу
Причина
Индексирование результирующего указателя на базу приведёт к обращению к некорректному объекту и, вероятно, к повреждению памяти.
Пример
struct B { int x; };
struct D : B { int y; };
void use(B*);
D a[] = { {1, 2}, {3, 4}, {5, 6} };
B* p = a; // плохо: a распадается до &a[0], который конвертируется в B*
p[1].x = 7; // перезаписывает a[0].y
use(a); // плохо: a распадается до &a[0], который конвертируется в B*
Контроль
- Помечать все комбинации распада массива и преобразований от базы к производному.
- Передавайте массив как
span, а не как указатель, и не позволяйте имени массива подвергаться преобразованию от производного к базовому до попадания вspan