C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 21:
[21.2] Converting Derived* Base* works OK; why doesn't Derived** Base** work?

Because converting Derived** Base** would be invalid and dangerous.

C++ allows the conversion Derived* Base*, since a Derived object is a kind of a Base object. However trying to convert Derived** Base** is flagged as an error. Although this error may not be obvious, it is nonetheless a good thing. For example, if you could convert Car** Vehicle**, and if you could similarly convert NuclearSubmarine** Vehicle**, you could assign those two pointers and end up making a Car* point at a NuclearSubmarine:

class Vehicle {
public:
  virtual ~Vehicle() { }
  virtual void startEngine() = 0;
};

class Car : public Vehicle {
public:
  virtual void startEngine();
  virtual void openGasCap();
};

class NuclearSubmarine : public Vehicle {
public:
  virtual void startEngine();
  virtual void fireNuclearMissle();
};

int main()
{
  Car   car;
  Car*  carPtr = &car;
  Car** carPtrPtr = &carPtr;
  Vehicle** vehiclePtrPtr = carPtrPtr;  // This is an error in C++
  NuclearSubmarine  sub;
  NuclearSubmarine* subPtr = ⊂
  *vehiclePtrPtr = subPtr;
  // This last line would have caused carPtr to point to sub !
  carPtr->openGasCap();  // This might call fireNuclearMissle()!
  ...
}
In other words, if it were legal to convert Derived** Base**, the Base** could be dereferenced (yielding a Base*), and the Base* could be made to point to an object of a different derived class, which could cause serious problems for national security (who knows what would happen if you invoked the openGasCap() member function on what you thought was a Car, but in reality it was a NuclearSubmarine!!). Try the above code out and see what it does — on most compilers it will call NuclearSubmarine::fireNuclearMissle()!

(BTW you'll need to use a pointer cast to get it to compile. Suggestion: try to compile it without a pointer cast to see what the compiler does. If you're really quiet when the error message appears on the screen, you should be able to hear the muffled voice of your compiler pleading with you, "Please don't use a pointer cast! Pointer casts prevent me from telling you about errors in your code, but they don't make your errors go away! Pointer casts are evil!" At least that's what my compiler says.)

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

(Note: there is a conceptual similarity between this and the prohibition against converting Foo** to Foo const**.)