C++ 从动态_cast获取非常量引用

C++ 从动态_cast获取非常量引用,c++,inheritance,reference,polymorphism,dynamic-cast,C++,Inheritance,Reference,Polymorphism,Dynamic Cast,是否可以从动态强制转换获取对基类指针的引用 #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

是否可以从动态强制转换获取对基类指针的引用

#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);
}
#包括
甲级{
公众:
虚拟~A(){}
};
B类:公共A{};
int main(){
A*A=新的B;
B*&B=动态投影(a);
//使用类型B的指针
b=new b;//这也应该改变a
断言(a==b);
}
编译此代码时没有出现错误
从类型为“B*”的右值初始化类型为“B*&”的非常量引用无效。
不,您不能


dynamic_cast(a)
将类型为
a*
a
转换为
B*
,它将构造类型为
B*
的临时文件并返回它。临时变量不能绑定到非常量左值引用。它可能绑定到常量引用,但以后不能根据需要更改它。

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

  • 目标类型为非参考(
    T
    ):prvalue
  • 目标类型是左值引用(
    T&
    ):左值
  • 目标类型为右值引用(
    T&
    ):xvalue
由于目标类型是非引用的
B*
,因此强制转换的结果是prvalue,它不能绑定到可变的左值引用

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

assert(typeid(*a) == typeid(B));
void* addr = dynamic_cast<void*>(a);
::new (addr) B;
assert(typeid(*a)=typeid(B));
void*addr=dynamic_cast(a);
::新地址B;
请注意,这无法运行析构函数,因此,如果代码依赖于析构函数的副作用,则行为是未定义的。不过,您可以先自己运行析构函数:

a->~A();                     // if A::~A is virtual
dynamic_cast<B*>(a)->~B();   // otherwise
a->~a();//如果A::~A是虚拟的
动态_cast(a)->~B();//否则