This does not compile in C++:
class A
{
};
class B : public A
{
};
...
A *a = new B();
B *b = dynamic_cast(a);
As the other stated: The standard says so.
So why does the standard says so?
Because if the type isn't polymorphic it may (or is? Question to the standard gurus) be a plain type. And for plain types there are many assumptions coming from the C backwards compatibility. One of those is that the type only consists of it's members as the developer declared + necessary alignment bytes. So there cannot be any extra (hidden) fields. So there is no way to store in the memory space conserved by A the information that it really is a B.
This is only possible when it is polymorphic as then it is allowed to add such hidden stuff. (In most implementations this is done via the vtable).
Because dynamic_cast
can only downcast polymorphic types, so sayeth the Standard.
You can make your class polymoprphic by adding a virtual
destructor to the base class. In fact, you probably should anyway (See Footnote). Else if you try to delete a B
object through an A
pointer, you'll evoke Undefined Behavior.
class A
{
public:
virtual ~A() {};
};
et voila!
There are exceptions to the "rule" about needing a virtual destructor in polymorphic types.
One such exception is when using boost::shared_ptr
as pointed out by Steve Jessop in the comments below. For more information about when you need a virtual destructor, read this Herb Sutter article.
From 5.2.7 (Dynamic cast) :
The result of the expression
dynamic_cast<T>(v)
is the result of converting the expression v to type T.[ ... multiple lines which refer to other cases ... ]
Otherwise v shall be a pointer to or an lvalue of a polymorphic type (10.3).
From 10.3 (Virtual functions) :
A class that declares or inherits a virtual function is called a polymorphic class.