从 dynamic_cast 获取非常量引用

Get non-const reference from dynamic_cast

是否可以从动态转换中获取对基 class 指针的引用?

#include <cassert>

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

class B : public A{};


int main(){
    A *a = new B;

    B *&b = dynamic_cast<B *>(a);

    // work with pointer as of type B

    b = new B; // this should change a aswell

    assert(a == b);
}

此代码未被编译,出现错误 invalid initialization of non-const reference of type 'B*&' from an rvalue of type 'B*'

不,你不能。

dynamic_cast<B *>(a); 会将类型为 A*a 转换为 B*,它将构造一个类型为 B* 和 return 的临时对象.临时变量不能绑定到非常量左值引用。它可能绑定到 const 引用,但您以后无法根据需要更改它。

任何强制转换表达式的值类别取决于强制转换的目标类型:

  • 目标类型是非引用(T):prvalue
  • 目标类型是左值引用(T&):左值
  • 目标类型是右值引用(T&&):xvalue

因为你的目标类型是 B*,一个非引用,转换的结果是一个纯右值,它不能绑定到一个可变的左值引用。

如果您要替换 *a 是其子对象的最派生对象,您可以尝试这样的操作:

assert(typeid(*a) == typeid(B));
void* addr = dynamic_cast<void*>(a);
::new (addr) B;

请注意,这无法 运行 析构函数,因此如果您的代码依赖于析构函数的副作用,则行为是未定义的。不过,您可以先 运行 自己的析构函数:

a->~A();                     // if A::~A is virtual
dynamic_cast<B*>(a)->~B();   // otherwise