当A和B没有共同的祖先时,通过dynamic_cast从A*转换为B*是否有效?

Con*_*tor 7 c++ inheritance dynamic-cast casting c++11

铛3.5.0克++ 4.9.0 编译下面的代码细(带-std=c++11 -Wall -Wextra -pedantic-errors)和程序输出true:

#include <iostream>

struct A
{
    virtual ~A() = default;
};

struct B
{
    virtual ~B() = default;
};

struct C : A, B
{
    virtual ~C() = default;
};

int main()
{
    C c;
    A* ap = &c;
    B* bp = dynamic_cast<B*>(ap);

    std::cout << std::boolalpha << (bp != nullptr) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*our 8

是.这有时被称为交叉投射,并且如果它们都是同一派生对象的基础子对象,则会成功,就像它们在这里一样.

dynamic_cast是必要的,因为转换需要两者都是C对象一部分的运行时信息.要进行静态转换,您必须明确转换为C*第一个.


chr*_*ris 7

是的,根据§5.2.7[expr.dynamic.cast],dynamic_cast<T>(v)(强调我的):

如果C是T指向或引用的类类型,则运行时检查在逻辑上执行如下:

- 如果在由v指向(引用)的大多数派生对象中,v指向(引用)C对象的公共基类子对象,并且如果只有一个C类对象从指向(引用)的子对象派生通过v结果点(引用)到该C对象.

- 否则,如果v指向(引用)最派生对象的公共基类子对象,并且最派生对象的类型具有类型C的基类,即明确且公共的,则结果点(引用)到最派生对象的C子对象.

- 否则,运行时检查失败.

在您的情况下,v指的是一个最派生的对象,它是您的实例C,但静态类型v是指向公共基类的指针A.C引文中提到的基类是你的B.