Согласно this,не имеет информации RTTI, поэтому литье из void*
не является законным и имеет смысл.dynamic_cast from "void *"
Если я правильно помню, dynamic_cast
от void*
работал над gcc.
Не могли бы вы прояснить проблему.
Согласно this,не имеет информации RTTI, поэтому литье из void*
не является законным и имеет смысл.dynamic_cast from "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
}
Это правда, что void*
не может быть dynamically_cast
ed.
Возможно, вы, вероятно, неправильно помните. С г ++ 4.5 и следующий код
struct A {
virtual ~A();
};
int main() {
A a;
void *p = &a;
A* pa = dynamic_cast<A*>(p);
}
Я получаю следующее сообщение об ошибке:
cannot dynamic_cast 'p' (of type 'void*') to type 'struct A*' (source is not a pointer to class)
Я предполагаю, что вы путаете с dynalic_cast
кvoid*
. Это является законным и получает указатель на наиболее производный объект класса.
dynamic_cast
отvoid*
является незаконным - тип отлиты из должен быть полиморфными - содержать по меньшей мере одну виртуальную функцию (отсчеты виртуальный деструктор тоже).
Вы можете наложить указатель на полиморфный тип на void *
, но не наоборот.
В 5.2.7 - Dynamic cast [expr.dynamic.cast]
он говорит, что для dynamic_cast<T>(v)
:
T
тип указателя, v
должен быть Rvalue указателя для завершения типа классаT
является ссылочным типом, v
должен быть lvalue полного типа класса (спасибо usta за комментарий к моему отсутствующему этому)...
v
должен быть указателем или именующим полиморфного типаТаким образом, нет, (void*)
значения а не допускаются.
Давайте подумаем о том, что ваш запрос может означать: скажем, у вас есть указатель, который на самом деле к Derived1*
, но код dynamic_cast
-ную только знает, что это 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*
предположительно указывает на начало производного объекта, тогда как вам нужен указатель на под-объект базового класса из которого извлекается литой тип.)
Если T - тип указателя, v должен быть rзначением указателя на полный тип класса, ... Если T является ссылочным типом, v должно быть lvalue полного типа класса, ... – usta
@usta: fixed , благодаря. –
Если класс класса, на который наложено, является однозначным доступным базовым классом класса класса литого выражения, в этом случае последнее не обязательно должно быть поли морфирующий. – usta