2010-07-25 293 views
6

铸造如果你有一个void *指针指向派生类来自BaseABaseB继承,编译器如何铸就void*指针BaseA*(或BaseB*)不知道该void*指针Derived类型的?多重继承

回答

5

它没有。使用static_cast铸造和从void*时的唯一保证是:

类型的指针的值,以对象转换为“指针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

编译器不会将void*指针强制转换为任何东西 - 程序员会这样做。

为了做什么有用的东西有void*指针,你需要明确它转换到非void*指针,如果你错了什么类型的指针实际指向的,你进入未定义行为市。

+0

您的回答是正确的。 从我的研究来看,如果派生扩展了BaseA和BaseB,则该对象在内存中布置为| BaseA | BaseB | Derived |。因此,指针指向BaseA的开始,所以将Derived引用到BaseB将让您阅读BaseA的成员。 – Chazz 2010-08-06 03:05:57