You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

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.
  • No labels