2010-07-25 1 views

ответ

5

Это не так. Единственной гарантией при литье в и из void* с использованием static_cast является:

Значение указателя типа на объект преобразуется в «указатель на cv void» и обратно к первоначальному типу указателя будет иметь свое первоначальное значение (С + +03 §5.2.9/10).

Например, следующий код неверен, потому что void* отливают типа, отличные от исходного типа указателя (последовательность приведения B1* ->void* ->B2*):

struct B1 { int i; }; 
struct B2 { int j; }; 

struct D : B1, B2 { }; 

D x; 
B1* b1ptr = &x; 
void* voidptr = b1ptr; 
B2* b2ptr = static_cast<B2*>(voidptr); 

Попытка использование b2ptr приведет к неопределенному поведению. Единственным типом, который можно безопасно отличить voidptr, является B1*, так как это тот тип, из которого был получен void* (ну или char*, так как все можно получить через char*).

3

Компилятор не использует указатель void* на что угодно - вы, программист, делаете.

Для того, чтобы сделать что-нибудь полезное с void* указателем, вам нужно в явном виде приводите его к не- void* указатель, и если вы не правы о том, что тип указателя на самом деле указывает на, вы вступаете Неопределенное поведение Город ,

+0

Ваш ответ верный. Из моего исследования, если Derived расширяет BaseA и BaseB, объект выкладывается в память как | BaseA | BaseB | Derived |. Таким образом, указатель указывает на начало BaseA, поэтому при отливке Derived to BaseB вы будете читать элементы BaseA. – Chazz

 Смежные вопросы

  • Нет связанных вопросов^_^