У вас есть массив типа "b", а не типа "a", и вы назначаете его указателю типа a. Полиморфизм не переносится в динамические массивы.
a* s
до
b* s
и вы увидите, что это начнет работать.
Только еще не связанные указатели могут быть обработаны полиморфно. Подумай об этом
a* s = new B(); // works
//a* is a holder for an address
a* s = new B[10]
//a* is a holder for an address
//at that address are a contiguos block of 10 B objects like so
// [B0][B2]...[B10] (memory layout)
когда вы перебираете массив с помощью s, подумайте о том, что используется
s[i]
//s[i] uses the ith B object from memory. Its of type B. It has no polymorphism.
// Thats why you use the . notation to call m() not the -> notation
перед преобразованием в массив, который у вас был
a* s = new B();
s->m();
s здесь просто адрес, а не статический объект, как s [i]. Просто адрес s все еще может быть динамически связан. Что у с? Кто знает? Что-то по адресу с.
См. Замечательный ответ Ari ниже для получения дополнительной информации о том, почему это также не имеет смысла с точки зрения того, как расположены массивы в стиле C.