2011-01-31 51 views
3

這是嚴格C.向下鑄造一個層次與非多類型

說你給一個基礎結構,以及2層派生的其他結構。這些派生結構不是從經典意義上推導出來的(即:A:B),相反,它們只包含基本類型的結構。所以,如果結構A爲基礎,B爲2層得到的結構之一,B會有A型的這樣一個成員:

struct A { 
    // blah blah... 
}; 

struct B { 
    A part_a; 
    // more stuff... 
} 

struct C { 
    A part_a; 
    // SO MUCH STUFF 
} 

假設你有一個功能,A_downcast_B,這樣的事情:

B * A_downcast_B(A * a) 
{ 
    // downcast the A* here somehow 
} 

您希望這個函數返回0-1如果'a'無法成功downcasted到B類型的結構。例如,如果C類型的「衍生」結構具有指向A*類型的指針,並且該指針已傳遞給此函數,則該函數將返回0,-1null

有沒有辦法做到這一點?我一直在想這幾個小時,這讓我很難過。

回答

8

struct A中嵌入某種類型的運行時類型信息是不可能的。例如,你可以存儲一個指向某種類型信息的指針,並且每當你創建任何「派生」結構時,你都必須初始化它。

struct RTTI { 
    const char *typename; 
    // etc. 
}; 

struct A { 
    const RTTI *rtti; 
    // rest of A 
}; 

struct B { 
    A part_a; 
    ... 
}; 

const RTTI RTTI_B = {"B"}; 

struct C { 
    A part_a; 
    ... 
}; 

const RTTI RTTI_C = {"C"}; 

void make_B(B *b) 
{ 
    b->part_a.rtti = &RTTI_B; 
    // make the rest of B 
} 

void make_C(C *c) 
{ 
    c->part_a.rtti = &RTTI_C; 
    // make the rest of C 
} 

B * A_downcast_B(A * a) 
{ 
    return (a->rtti == &RTTI_B) ? (B*)a : NULL; 
} 

注意,這僅僅是一個C++的dynamic_cast運營商,這不僅與多態數據類型的作品簡化實現。之所以這樣,是因爲運行時只能訪問運行時類型信息,如果對象中嵌入了某種類型的信息 - 它的vtable。

+1

OHHH所以這就是RTTI所代表的。該死的我懶惰不讓我谷歌大聲笑。非常感謝! :) – 2011-01-31 05:14:56