【问题标题】:dynamic_cast<D *>(pb) return nulldynamic_cast<D *>(pb) 返回 null
【发布时间】:2017-11-08 05:55:34
【问题描述】:

在 C++ 入门(第 5 期)19.2.1 中关于 dynamic_cast。它说,要让dynamic_cast&lt;type*&gt;(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。你有一个B
  • 你误会了。
  • @StoryTeller:由于pb 的类型为B*,它不能指向除B 以外的任何东西。
  • @KerrekSB - D is-a B 然而:P

标签: c++ dynamic-cast


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 明白你的想法,要求有点误导。谢谢
  • @YuanWen:不是。要求说你不能写像dynamic_cast&lt;double&gt;(4) 这样的东西。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多