Because pointer arithmetic does not take account of polymorphism, a major problem with arrays is that they do not interact well with polymorphism Stroustrup 06, Meyers 06 as the following example illustrates:
class Base { public: virtual void func(void) { cout << "Base" << endl; } }; class Derived : public Base { public: int i; Derived() { i = 0; } void func(void) { cout << "Derived " << ++i << endl; } }; void walk(class Base *bar, int count) { for (int i = 0; i < count; i++) { bar[i].func(); } } int main(void) { Base dis[5]; Derived dat[5]; walk(dis, 5); walk(dat, 5); // crashes } |
In the last call to {{walk()}}, {{dat\[\]}} is treated as a {{Base\[\]}} and the subscripting no longer works correctly when {{sizeof(Derived) \!= sizeof(Base)}}. This is because {{walk()}} incorrectly believes that the size of each element in {{bar\[\]}} is {{sizeof(Base)}}. To locate the second element in the array (located at {{bar\[1\]}}), {{walk()}} adds the {{sizeof(Base)}} to the address {{bar}}. Assuming the derived object is larger (which is often the case), the resulting pointer refers to a point within the first element and not to the start of the second element located at {{bar + sizeof(Derived)}}. |