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
Code Block |
---|
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
}
|
Wiki Markup |
---|
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.