virtual function resolution happens with pointer/reference and not with object. Now consider below example:
struct Base { virtual void foo (); };
struct Derived : Base { void foo (); };
Derived d[2];
Base *p = d;
p[0].foo(); // calls Derived::foo()!
My perception was like this: for any array T arr[SIZE]; the type of arr[N] is T (and not T&), i.e. arr[N] is an object. Had it been a case, then in above sample p[0] would call Base::foo(), because p[0] should resolved to an object.
However, it’s wrong. Can someone explain, why p[0] is resolving to Base& and not Base ? Is it because p[0].foo() is equivalent to (p+0)->foo()?
You got it — it is the “array indirection operation”.
The following are equivolent:
It’s in the standard: Literally, the “array indirection operation” means that
*(a + n)substitutes fora[n], so the result is a reference to an object, not a copy-constructed value of an object.This was essential to get polymorphism to work, and to ensure derive types were not “copy-constructed” to base types.
Extending further, the following are also equivolent, and result in a reference-to-object:
[EDIT] To be explicit, in your example, yes, these are exactly equivalent: