dynamic_cast<D *>(pb) 返回空值

dynamic_cast<D *>(pb) return null

本文关键字:pb 空值 gt 返回 cast lt dynamic      更新时间:2023-10-16

在C++入门(5th)19.2.1中关于dynamic_cast。它说,为了dynamic_cast<type*>(e)成功,

E 的类型必须是公共派生自的类类型 目标类型、目标类型的公共基类或与目标相同 类型

但是,对于以下代码:

class B{
  public:
    virtual ~B(){}
};
class D : public B{};
B *pb = new B;
D *pd = dynamic_cast<D*>(pb);
if(pd == 0) cout << "err" << endl;

输出为"错误"。但是 pb 的类型是 D 类型的公共基类。

这是C++入门(第5版)中的错误吗?还是我只是误解了这些话?

pb的类型确实是D的公共基类,但pb指向的对象不是任何类型D对象的基子对象。动态强制转换检测到这一点并返回 null。

如果您确实尝试将指针强制转换为 D 对象的基子对象,您将获得指向D对象的(非 null)指针:

D obj;
B *pb = &obj;   // points at subobject
assert(&obj == dynamic_cast<D*>(pb));

您引用的要求只是一个静态要求,它允许您使用动态强制转换 - 但它没有描述使用强制转换的结果。这在后面会描述。

dynamic_cast可以用作检测一个对象是否派生自另一个对象的工具,在您编写的代码中,答案是否定的,因此您得到了一个 null。由

B *pb = new B;
D *pd = dynamic_cast<D*>(pb);

你正在将一个基础向下投射到派生的,这与文档所说的相反。当然,如果pb指向一个扩展D*,你可以有下面:

B *pb = new D; // <--- It is a `D`
D *pd = dynamic_cast<D*>(pb);