dynamic_cast<D *>(pb) return 空

dynamic_cast<D *>(pb) return null

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

the type of e must be either a class type that is publicly derived from the target type, a public base class of the target type, or the same as the target type

但是,对于下面的代码:

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;

输出为"err"。但是 pb 的类型是 public base class 类型 D.

这是C++ primer(5th)的错误吗?还是我误解了这些话?

dynamic_cast 可以用作检测一个对象是否派生自另一个对象的工具,在您编写的代码中,答案是否定的,所以您得到了一个空值。通过

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

您正在将基数向下转换为派生数,这与 documet 所说的相反。当然,如果 pb 指向一个确切的 D*:

,你可以有下面的内容
B *pb = new D; // <--- It is a `D`
D *pd = dynamic_cast<D*>(pb);

pb的类型确实是D的public基class,但是pb指向的对象是不是 D 类型的任何对象的基础子对象。动态转换检测到这一点并且 returns null.

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

D obj;
B *pb = &obj;   // points at subobject

assert(&obj == dynamic_cast<D*>(pb));

您引用的要求只是允许您使用动态转换的静态要求 -- 但它没有描述使用转换的结果 .后面会讲到。