从dynamic_cast

时间:2016-05-29 09:49:01

标签: 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 should change a aswell

    assert(a == b);
}

此代码未使用错误invalid initialization of non-const reference of type 'B*&' from an rvalue of type 'B*'

进行编译

2 个答案:

答案 0 :(得分:3)

不,你不能。

dynamic_cast<B *>(a);会将a类型A*转换为B*,它会构建一个B*类型的临时表并将其返回。临时变量不能与非常量左值引用相关联。它可能绑定到const引用,但您可以随后根据需要进行更改。

答案 1 :(得分:1)

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

  • 目的地类型为非参考(T):prvalue
  • 目的地类型是左值 - 参考(T&):左值
  • 目的地类型是rvalue-reference(T&&):xvalue

由于您的目标类型为B*,非引用,因此转换的结果是一个prvalue,它不能绑定到可变的左值引用。

如果你试图替换*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