В соответствии с этим, 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 *, но не наоборот.