There's a very subtle problem with using raw built-in arrays. Consider this:
void f(Base* arrayOfBase) { arrayOfBase[3].memberfn(); } main() { Derived arrayOfDerived[10]; f(arrayOfDerived); }The compiler thinks this is perfectly type-safe, since it can convert a Derived* to a Base*. But in reality it is horrendously evil: since Derived might be larger than Base, the array index in f() not only isn't type safe, it may not even be pointing at a real object! In general it'll be pointing somewhere into the innards of some poor Derived.
The root problem is that C++ can't distinguish between a ptr-to-a-thing and a ptr-to-an-array-of-things. Naturally C++ "inherited" this feature from C.
Note: if we had used an array-like class instead of using a raw array (e.g., an "Array<T>" rather than a "T[]"), this problem would have been properly trapped as an error at compile time rather than at run-time.