Краткий ответ: в C++ массивы значений никогда не являются полиморфными, даже если их содержимое и не может быть обработано так. То есть вы не можете обработать derived ad[N]
, как если бы это был base ab[N]
.
Длинный ответ: причина этого глубоко погружена в арифметику указателя на C. Если у вас есть int* pi
и увеличьте его ++pi
, он не будет просто увеличиваться до следующего адреса памяти. Если бы это было так, это не указывало бы на следующий int
, так как это не начинается с следующего адреса. Таким образом, вместо указателя добавляется sizeof(int)
байт. (Конкретный пример может помочь: На архитектурах с 8-битными char
типами - char
, будучи по определению, что C и C++ считают размер байта архитектуры - и 32 бит int
типов, int
имеет размер 4 байта. Таким образом, ++pi
добавит 4 к адрес указателя, так что он указывает на следующий int
.) Такая же арифметика применяется ко всем другим операциям указателя. Так, например, с int* pi2=pi+1
, pi2
укажут sizeof(int)
байт за pi
, хотя pi2-pi
даст 1.
Таким образом, предполагая, что вы поняли последний абзац, давайте вернемся к массивам. Если у вас есть массив derived ad[N]
, адрес ad[1]
равен sizeof(derived)
байт, превышающим адрес .(Это не относится к выравниванию, чтобы не усложнять проблему.) Однако, если у вас есть base* pb
, указывающий на , приращение его приведет к тому, что он будет указывать sizeof(base)
за адресом первого элемента - который, если (как в случае с ваш пример) sizeof(base) < sizeof(derived)
, is не адрес ad[1]
, но где-то посередине ad[0]
.
Единственное, что вы можете сделать, чтобы обработать содержимое массива, как если бы это было все базовые классы, чтобы перебрать массив с помощью derived*
и отбрасывать этот указатель base*
в цикл:
derived d[5];
derived* begin = d;
const derived* end = d + sizeof(d)/sizeof(d[0]); // points one beyond the last element
while(begin != end)
{
base* pb = begin;
cout<< pb->_bval;
++begin;
}
(Обратите внимание, что я также сменил ваш код на использование идиоматических итераций начала и конца C++.)
Спасибо за то, что вы точны. –