В соответствии с этим, void*
не имеет информации RTTI, поэтому кастинг из void*
не является законным и имеет смысл.
Если я правильно помню, dynamic_cast
из void*
работал над gcc.
Можете ли вы прояснить проблему.
В соответствии с этим, void*
не имеет информации RTTI, поэтому кастинг из void*
не является законным и имеет смысл.
Если я правильно помню, dynamic_cast
из void*
работал над gcc.
Можете ли вы прояснить проблему.
dynamic_cast
работает только с полиморфными типами, то есть с классами, содержащими виртуальные функции.
В gcc вы можете dynamic_cast
на void*
, но не из:
struct S
{
virtual ~S() {}
};
int main()
{
S* p = new S();
void* v = dynamic_cast<void*>(p);
S* p1 = dynamic_cast<S*>(v); // gives an error
}
В 5.2.7 - Dynamic cast [expr.dynamic.cast]
говорится, что для dynamic_cast<T>(v)
:
T
- тип указателя, v
должен быть rзначением указателя на полный тип классаT
является ссылочным типом, v
должен быть lvalue полного типа класса (спасибо usta за комментарий к моему отсутствующему этому)...
v
должен быть указателем на или значением полиморфного типаИтак, нет, значение (void*)
не разрешено.
Подумайте о том, что может означать ваш запрос: скажем, у вас есть указатель, который действительно соответствует Derived1*
, но код dynamic_cast
-ing знает только это void*
. Скажем, вы пытаетесь передать его в Derived2*
, где оба производных класса имеют общую базу. Поверхностно, вы можете подумать, что все указатели указывают на тот же объект Base
, который будет содержать указатель на соответствующую таблицу виртуальной диспетчеризации и RTTI, чтобы все могло висеть вместе. Но рассмотрим, что производные классы могут иметь несколько базовых классов, и поэтому необязательный подэкземпляр Base
может быть не тем, к которому указывает Derived*
- доступный только как void*
-. Это не сработает. Вывод: компилятор должен знать эти типы, чтобы он мог выполнять некоторую настройку указателей на основе соответствующих типов.
Derived1* -----> [AnotherBase] [[VDT]Base] <-- but, need a pointer to start of [extra members] this sub-object for dynamic_cast
(В некоторых ответах говорится о необходимости того, чтобы указатель, который вы выбрали, имел полиморфный тип, имеющий виртуальные функции. Это все допустимо, но немного вводит в заблуждение. Как вы можете видеть выше, даже если void*
к такому типу, он все равно не будет надежно работать без полной информации о типе, поскольку реальная проблема заключается в том, что void*
предположительно указывает на начало производного объекта, тогда как вам нужен указатель на под-объект базового класса из которого получается литой тип.)
Верно, что void*
не может быть dynamically_cast
ed из.
Вероятно, вы неправильно помните. С g++ 4.5 и следующий код
struct A {
virtual ~A();
};
int main() {
A a;
void *p = &a;
A* pa = dynamic_cast<A*>(p);
}
Я получаю следующую ошибку:
не может dynamic_cast 'p' (типа 'void *') набирать 'struct A *' (источник не является указателем на класс)
Я думаю, вы путаете с dynamic_cast
void*
. Это является законным и получает указатель на наиболее производный объект класса.
dynamic_cast
from void*
является незаконным - тип, который должен быть издан, должен быть полиморфным - содержать хотя бы одну виртуальную функцию (счетчик виртуальных деструкторов тоже).
Вы можете наложить указатель на полиморфный тип на void *
, но не наоборот.