A base class array stores elements as the base type. Although a derived-object pointer can replace a base-object pointer, a derived array cannot safely replace a base array: indexing advances by the base type's size. section 8.10
Mistake: passing a derived array as a base array
With B and D : public B, printArray(const B a[]) accepts both B* and D*. A B array prints four zeroes and destroys four B objects. A D array prints alternating values because a[i] advances as if each element were only a B; deleting it through B* destroys only the B subobjects, as the output demonstrates. section 8.10
Listing 8.19 Passing an array with derived elements
const int SIZE = 4;
class B {
private:
int n;
public:
B(int n=0) : n(n) {}
~B() { std::cout << "destroying B\n"; } #1
int getN() const { return n; } #2
};
class D : public B {
int m;
public:
D() : B(0), m(1) {}
~D() { std::cout << "destroying D\n"; }
};
void printArray(const B a[]) {
for (int i = 0; i < SIZE; ++i)
std::cout << a[i].getN() << '\n'; #3
}
void deleteArray(const B a[]) { #4
delete [] a;
}
int main() {
B* bs = new B[SIZE];
printArray(bs);
deleteArray(bs);
D* ds = new D[SIZE];
printArray(ds);
deleteArray(ds);
return 0;
}
Inspect the complete failing example, including the base and derived classes, array-processing functions, and observed output. section 8.10
Avoid pretending that array parameters provide polymorphic element handling. Make the function type-preserving with a template, so B* uses B indexing and D* uses D indexing; the corrected version prints consistent values and destroys both D and B parts. section 8.10
