Чтобы лучше понять мой вопрос, я имею в виду тему, обсуждаемую в книге «Язык программирования C++ 4-го издания», глава 27, раздел 2.1.Почему примитивный массив полиморфных типов опасен
Автор говорит об опасности полиморфных типов и встроенных массивов. Он приводит следующий пример:
void maul(Shape∗ p, int n) // Danger!
{
for (int i=0; i!=n; ++i)
p[i].draw(); //looks innocent; it is not
}
void user()
{
Circle image[10]; // an image is composed of 10 Circles
// ...
maul(image,10); // ‘‘maul’’ 10 Circles
// ...
}
Мы сказали, что форма является абстрактным размер размера 4 и Circle наследует Shape и добавить дополнительный 2 членов, центр и радиус, который добавляет к размеру типа, следовательно, sizeof(Circle)>sizeof(Shape)
. Теперь автор объясняет, что, учитывая следующее мнение, например:
user() view: image[0] image[1] image[2] image[3]<br/>
maul() view: p[0] p[1] p[2] p[3]
Вызов p[1].draw()
(акцент на р [], при р [0] будет называть правильной функции) потерпит неудачу, потому что там нет указателя виртуальной функции, где это ожидалось.
Теперь я знаю, как работают таблицы виртуальных функций, но я не понимаю, как размер типа или его макета влияет на вызов виртуальной функции? Когда компилятор видеть вызов виртуальной функции она не заменить его чем-то похожее на:
p[1]._vfptr->draw_impl();
Предполагая, что я прав, то как размер полученного объекта/его расположение нарушило призыв Это.
Как вы ожидаете совершить вызов виртуальной функции, если у вас даже нет правильных адресов объектов «Круг»? – Brian
Вы понимаете, что 'image + 1! = P + 1'? – Jarod42
Спасибо, что объяснил, я читал про нарезку, и это дало понять мне. –