We know that dynamic_cast<void*> will cast a pointer to the pointer to the most derived object; but what if the underlying object is not the most derived? For example:
class BaseClass { public: virtual void dummy() { std::cout << "Base\n"; } };
class DerivedClass : public BaseClass {
int a{};
public:
void dummy() { std::cout << "Derived\n"; }
};
class MostDerivedClass : public DerivedClass {
int b{};
public:
void dummy() { std::cout << "Most\n"; }
};
BaseClass* basePtr_d = new DerivedClass, *basePtr_md = new MostDerivedClass;
DerivedClass* derivedPtr =
dynamic_cast<DerivedClass*>(basePtr_d); // right
MostDerivedClass* mostDerivedPtr =
dynamic_cast<MostDerivedClass*>(basePtr_md); // right
MostDerivedClass* mostDerivedPtr2 =
static_cast<MostDerivedClass*>(dynamic_cast<void*>(basePtr_md)); // right
DerivedClass* derivedPtr2 =
static_cast<DerivedClass*>(dynamic_cast<void*>(basePtr_d)); // What happens??
What happens for the last case?
The rule is:
It's easy to miss the important distinction: the pointer type and the pointer value, the later being sometimes referred to as the dynamic type of a pointer.
When
Bderives fromA, a pointer of typeA*and a pointer of typeB*both pointing to the same object of typeBmight have a different values. The restriction ondynamic_cast<void*>covers this specificity and guarantees a return value for the most derived type, even though the static type of the returned pointer is of coursevoid*. This is still true if there exist a typeCderiving fromBorA.