2016-05-29 2 views
2

Возможно ли получить ссылку на указатель базового класса из динамического каста?Получить ссылку на константу из 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*'

ответ

3

Нет, вы не можете.

dynamic_cast<B *>(a); преобразует a с типом A* в B*, он будет построен временный типа B* и вернуть его. Временная переменная не может быть привязана к неконстантной задаче lvalue. Это может быть связано с константой ссылки, но вы не можете изменить ее позже, как хотите.

1

Категория значения любого выражения отлитого зависит от типа назначения слепка:

  • типа назначения является неэталонным (T): prvalue
  • типа назначения является именующей-ссылкой (T&): Lvalue
  • тип назначения является Rvalue ссылка (T&&): xvalue

Поскольку ваш тип назначения B*, без ссылки, результат приведения - это prvalue, который не может связываться с изменяемой ссылкой lvalue.

Если вы пытаетесь заменить наиболее производный объект которого *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 
Смежные вопросы