Section 21:
 21.1 Should I hide member functions that were public in my base class? 21.2 Errors trying to convert Derived** → Base**? 21.3 Is a parking-lot-of-Car a kind-of parking-lot-of-Vehicle? 21.4 Is an array of Derived a kind-of array of Base? 21.5 Does array-of-Derived is-not-a-kind-of array-of-Base mean arrays are bad? 21.6 Is a Circle a kind-of an Ellipse? 21.7 Are there other options to the "Circle is/isnot kind-of Ellipse" dilemma? 21.8 Why does this Circle-kind-of-Ellipse problem seem confusing? 21.9 Perhaps Ellipse should inherit from Circle then? 21.1 But my problem doesn't have anything to do with circles and ellipses, so what good is that silly example to me? 21.11 How could "it depend"??!? Aren't terms like "Circle" and "Ellipse" defined mathematically? 21.12 Is SortedList a kind-of List?
[21.4] Is an array of Derived a kind-of array of Base?

Nope.

This is a corollary of the previous FAQ. Unfortunately this one can get you into a lot of hot water. Consider this:

```class Base {
public:
virtual void f();             // 1
};

class Derived : public Base {
public:
...
private:
int i_;                       // 2
};

void userCode(Base* arrayOfBase)
{
arrayOfBase[1].f();           // 3
}

int main()
{
Derived arrayOfDerived[10];   // 4
userCode(arrayOfDerived);     // 5
...
}
```
The compiler thinks this is perfectly type-safe. Line 5 converts a Derived* to a Base*. But in reality it is horrendously evil: since Derived is larger than Base, the pointer arithmetic done on line 3 is incorrect: the compiler uses sizeof(Base) when computing the address for arrayOfBase[1], yet the array is an array of Derived, which means the address computed on line 3 (and the subsequent invocation of member function f()) isn't even at the beginning of any object! It's smack in the middle of a Derived object. Assuming your compiler uses the usual approach to virtual functions, this will reinterpret the int i_ of the first Derived as if it pointed to a virtual table, it will follow that "pointer" (which at this point means we're digging stuff out of a random memory location), and grab one of the first few words of memory at that location and interpret them as if they were the address of a C++ member function, then load that (random memory location) into the instruction pointer and begin grabbing machine instructions from that memory location. The chances of this crashing are very high.

The root problem is that C++ can't distinguish between a pointer-to-a-thing and a pointer-to-an-array-of-things. Naturally C++ "inherited" this feature from C.

NOTE: If we had used an array-like class (e.g., std::vector<Derived> from the standard library) instead of using a raw array, this problem would have been properly trapped as an error at compile time rather than a run-time disaster.

(Note: this FAQ has to do with public inheritance; private and protected inheritance are different.)