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:
Non-compliant Example
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).
Compliant Solution
References
- Meyers 06 Item 3: Never treat arrays polymorphically.
- Stroustrup 06 What's wrong with arrays?