代码之家  ›  专栏  ›  技术社区  ›  Filip Frącz

常见问题解答:为什么动态强制转换只在一个类至少有一个虚拟方法时才起作用?

  •  15
  • Filip Frącz  · 技术社区  · 15 年前

    这在C++中是不编译的:

    class A
    {
    };
    
    class B : public A
    {
    };
    
    ...
    
    A *a = new B();
    B *b = dynamic_cast<B*>(a);
    
    3 回复  |  直到 15 年前
        1
  •  29
  •   Community Mohan Dere    8 年前

    因为 dynamic_cast 只能向下转换多态类型,因此标准是这样说的。

    你可以通过添加 virtual 基类的析构函数。事实上,你可能无论如何都应该(见脚注)。否则,如果您试图删除 B 通过 A 指针,你会唤起 Undefined Behavior .

    class A
    {
    public:
      virtual ~A() {};
    };
    

    等一下!

    脚注

    在多态类型中需要虚拟析构函数的“规则”有一些例外。
    其中一个例外是 boost::shared_ptr 正如史蒂夫·杰索普在下面的评论中指出的那样。有关何时需要虚拟析构函数的更多信息,请阅读以下内容 Herb Sutter 文章。

        2
  •  9
  •   mmmmmmmm    15 年前

    另一种说法是:标准是这样说的。

    为什么标准会这么说?

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

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

        3
  •  8
  •   icecrime    15 年前

    从5.2.7(动态铸造)开始:

    表达式的结果 dynamic_cast<T>(v) 是 将表达式v转换为类型T。

    [ ... 多行引用其他情况。。。]

    否则v应为 指向或左值的 多态型(10.3)。

    从10.3(虚拟功能)开始:

    声明或继承 虚函数称为 多态类。