2010-07-25 121 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