关于c ++:常见问题解答:为什么dynamic_cast仅在类具有至少1个虚方法的情况下起作用?

FAQ: Why does dynamic_cast only work if a class has at least 1 virtual method?

这不能在C ++中编译:

1
2
3
4
5
6
7
8
9
10
11
12
class A
{
};

class B : public A
{
};

...

A *a = new B();
B *b = dynamic_cast<B*>(a);


因为dynamic_cast只能向下转换多态类型,所以说标准。

您可以通过在基类中添加一个virtual析构函数来使您的类成为多态的。实际上,无论如何,您可能都应该这样做(请参阅脚注)。否则,如果尝试通过A指针删除B对象,则会引起未定义行为。

1
2
3
4
5
class A
{
public:
  virtual ~A() {};
};

等等!

脚注

对于需要多态类型的虚拟析构函数的"规则"有一些例外。
一种例外是使用boost::shared_ptr时,如Steve Jessop在下面的注释中所指出的。有关何时需要虚拟析构函数的更多信息,请阅读此Herb Sutter文章。


就像其他人所说的:标准是这样说的。

那么为什么标准这么说呢?

因为如果类型不是多态的,则它可能是(或是标准大师的问题)是普通类型。对于普通类型,有许多来自C向后兼容性的假设。
其中之一是,类型仅由开发人员声明的成员+必要的对齐字节组成。因此,不能有任何其他(隐藏)字段。
因此,无法在A所保存的内存空间中存储它确实是B的信息。

仅当它是多态的时才有可能,因为这样才可以添加此类隐藏的内容。
(在大多数实现中,这是通过vtable完成的)。


从5.2.7(动态转换):

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).

从10.3(虚拟功能)开始:

A class that declares or inherits a
virtual function is called a
polymorphic class.