Кастинг с множественным наследованием - PullRequest
6 голосов
/ 25 июля 2010

Если у вас есть пустой указатель * на производный класс, который наследуется от BaseA и BaseB, как компилятор преобразует указатель void* в BaseA* (или BaseB*), не зная, что void* указатель имеет тип Derived?

Ответы [ 2 ]

5 голосов
/ 25 июля 2010

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

Значение указателя типа на объект, преобразованное в «указатель на cv void» и обратно в исходный указательТип будет иметь свое первоначальное значение (C ++ 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 голосов
/ 25 июля 2010

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

Чтобы сделать что-нибудь полезное с указателем void*, вам нужно явно привести его к не-1007 * указателю, и если вы ошибаетесь в том, на какой тип указатель действительно указывает к, вы вводите неопределенный город поведения.

...