2016-05-29 49 views
2

是否可以從動態轉換獲取對基類指針的引用?從dynamic_cast獲取非const引用

#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*'

回答

3

沒有編譯,你不能。

dynamic_cast<B *>(a);將轉換aA*類型B*,將構建一個臨時B*類型和返回。臨時變量不能加入非常量左值引用。它可能會被綁定到const引用,但是你不能隨意改變它。

1

任何鑄造表達式的值類別取決於鑄件的目的地類型:

  • 目的地類型是非參考(T):prvalue
  • 目的類型是左值參考(T&):左值
  • 目的類型是右值參考(T&&):x值

由於您的目標類型爲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