2017-10-05 107 views
2

在SDL的API文檔Union event中說它的字段類型是聯合中所有事件(對象)共享的,這怎麼可能?聯盟和共享數據字段(C++)

還例如,這是完全合法的

while(SDL_PollEvent(&event)){ 

    if(event.type == SDL_KEYDOWN){ 


    cout << "key down" << endl; 
    } 

,這也是工作在邏輯上更有意義,我,但我不知道怎麼樣,首先是甚至法律

while(SDL_PollEvent(&event)){ 

    if(event.key.type == SDL_KEYDOWN){ 


     cout << "key down" << endl; 
    } 
+0

不要忘記標記正確的答案(使用複選標記),一旦您滿意相同的作用。 – BTownTKD

回答

1

一個工會有可能代表一個多出多種可能類型/結構。

union { 
    int i; 
    float f; 
    char c; 
}; 

在上面的例子中,保持該聯合可以表示int一個float一個char存儲器。但它只能是一個的那些東西;他們是相互排斥的。該聯合與每個成員使用的基礎字節重疊以節省空間,並假定您將知道如何正確解釋它。 (注意:爲了適應這種情況,聯合的'大小' - 存儲聯合的字節雲 - 必須足夠大以容納聯合中定義的最大可能類型,在這種情況下, int或float可能每個都是4個字節,所以聯合會至少有4個字節。)

這個重疊的內存'技巧'的一個整齊的副作用;如果工會描述多個struct成員,那麼他們可以共享公共領域。

實施例:

union { 
    struct { 
    int type; 
    int i; 
    } OPTION_INT; 

    struct { 
    int type; 
    float f; 
    } OPTION_FLOAT; 

    struct { 
    int type; 
    char c; 
    } OPTION_CHAR; 
}; 

好的,整齊;工會可以代表三種可能的結構中的任何一種。儘管如此,他們都包含完全相同的第一個成員 - type。由於內存被「重疊」的方式,OPTION_INT type成員共享與OPTION_FLOAT和OPTION_CHAR成員相同的內存。因此,無論哪個選項是正確的,type成員應該始終存在。這是可能的,因爲他們都將type字段定義爲第一個成員。

+0

哇謝謝,令人驚歎的詳細答案非常感謝=),這使得很多的感覺 – irishmaniac

+0

儘管巧妙的技巧可能會起作用,它不必在C++中,並不能保證工作。爲了獲得最好的結果[堅持POD類型](http://en.cppreference.com/w/cpp/concept/PODType),如果它絕對必須工作,即使在編譯器設計者做出意外的情況下, ''從內部'struct's並將'union'包裝在'''struct'中,其中包含'type'。 – user4581301

+0

我對該陳述提出質疑;它在C中是絕對保證的 - 在語言規範中有一個關於聯合的通用初始成員的特殊條款 - 但我不知道C++規範是否足夠了解這個子句是否缺失。我的理解是C是C++的完整子集,這意味着C++中存在相同的保證。 – BTownTKD

0

工會 - gotta love'em :)在Java中沒有真正的等價物,所以很多Java開發人員都覺得它們很奇特。一個聯盟在概念上有點像一個抽象類 - 一個聯盟可以有不同類型的數據打包進去。數據類型通常有一種父子繼承關係 - 他們在這種情況下 - 但它們不是必需的。例如,看到一個由整數和雙精度組成的聯合並不罕見 - 在這種情況下,這不是一個包含整數的整數的數據結構,而是包含一個整數的整數或一個整數的整數或者在一些特定的內存塊中加倍。實際使用的類型必須在運行時確定。

在這種情況下,SDL_Event聯合會模擬許多不同種類的事件。第一個字段type指示應如何解釋其餘數據。如果類型爲SDL_KEYDOWN,則聯合應該被解釋爲SDL_KeyboardEvent類型的結構。SDL_KeyboardEvent的第一個字段也是type - 這是有道理的,因爲它與「基本」SDL_Event包裝在同一個空間。你可以考慮type(稍微)像「base」SDL_Event的一個屬性,它可以是(某種)特定子類型繼承的。我在這裏有點wa because,因爲這個比喻並不是那麼強大。

在任何情況下,編譯器都會確保SDL_Event的大小足以存儲任何定義爲包含的不同結構。除了type,具體結構SDL_DropEventSDL_KeyboardEvent等沒有很多共同點,通過查看它們的定義可以看出。

在Java AWT,事件類執行幾乎完全一樣SDL_Event工會確實在SDL與C

+0

感謝凱文超級詳細的答案=)現在有道理,是的,這是非常不同的Java,但我認爲這是非常酷的概念 – irishmaniac