2012-08-12 55 views
1

我很好奇如何鑄造派生指針和基類實際上工作。 下面是一個例子:多態性:運行時間鑄造指針

struct A {}; 
struct B : A {}; 

// Boxing a pointer to an instance of B 
void* p = new B(); 

現在,let's說,我想通過指針p訪問的可能成員或方法。

A* a1 = (A*)p; 
A* a2 = (A*)((B*)p); 

哪一個是正確的?有沒有區別?
你能告訴我在哪裏我可以得到關於這個問題的進一步信息?

+1

如果您正在使用C++,那麼應該更喜歡C++風格的轉換。 – iammilind 2012-08-12 12:42:08

+1

這裏沒有裝盒。 – Puppy 2012-08-12 12:51:47

+0

我看到的唯一細微差別是在第二次演員中創建了兩個臨時指針對象,而首先它只有一個指針對象:P – 2012-08-12 13:11:56

回答

1

在這種情況下,在實踐中沒有區別。

但有可能是差if there is multiple inheritance

#include <cstdio> 

struct A { int x; }; 
struct B { int y; }; 

struct C : B, A {}; 

int main() { 
    void* c = new C(); 
    printf("%p\n", c);    // 0x1000 
    printf("%p\n", (A*) c);  // 0x1000 
    printf("%p\n", (A*) ((C*) c)); // 0x1004 
    return 0; 
} 

或子類具有虛擬方法,但父不[1],包括使用虛擬繼承[2]

在標準方面,由於OP使用C型表演,因此which in this case is equivalent to static_cast

鑄造序列B*void*B*A*是有效的,其中所要求的§5.2.9[expr.static.cast]/13中的第一兩個投將返回相同的指針,最後鑄造作品作爲指針轉換§4.10[conv.ptr]/3。

然而,鑄造序列B*void*A*將實際得到未定義結果,因爲,結果不會在§5.2.9/ 13☺限定。


[1]

#include <cstdio> 

struct A { int x; }; 
struct C : A { virtual void g() {} }; 

int main() { 
    void* c = new C(); 
    printf("%p\n", c);    // 0x1000 
    printf("%p\n", (A*) c);   // 0x1000 
    printf("%p\n", (A*) ((C*) c)); // 0x1008 
    return 0; 
} 

[2]

#include <cstdio> 

struct A { int x; }; 
struct C : virtual A {}; 

int main() { 
    void* c = new C(); 
    printf("%p\n", c);    // 0x1000 
    printf("%p\n", (A*) c);   // 0x1000 
    printf("%p\n", (A*) ((C*) c)); // 0x1008 
    return 0; 
} 
+3

Ewwww。 'printf',真的嗎? – Puppy 2012-08-12 12:52:20

+1

感謝您的回答。 我想我明白你在帖子中描述的內容。 爲了我的目的,它會做。 – 2012-08-12 13:14:08

+0

@DeadMG:''糟透了,就是這樣。 – kennytm 2012-08-12 14:31:19