2015-03-03 63 views
3

雖然它的確不會增加我的問題,但讓我開始說我的背景比C/C++等Java和C#語言要重得多我的許多疑惑無疑來自這些差距。將1字節值和3字節值打包成單個32位結構

我有一個C++應用程序,可以在任何給定的時間從多達255個不同的數據源加載對象。每個共享數據源都分配了一個GUID。其中一個數據源中的每個對象都被鍵入一個24位索引。我將這些數據對象稱爲資源

因爲每個數據源都按順序對資源進行索引,所以對任何資源的引用都包括24位索引和一個額外的字節,以確定給定上下文中的數據源。從而消除運行時環境中的歧義。

如果數據對象包含對同一數據源中資源的引用,則該字節將加載0值。如果它引用另一個數據源中的對象,則該字節將作爲數據源的「依賴關係表」的索引,其中包含最多128個用於其他數據源的GUID。

我傾向於定義這些資源鍵的C-結構爲:

typedef struct ResourceID { 
    char DataSourceIndex; 
    char[3] ResourceIndex; 
} ResourceID; 

的問題是,之前在我的應用程序的工廠類,可以建立一個完整的資源對象,它必須解決的DataSourceIndex每個ResourceID都與應用程序自己的運行時上下文表(最多255個GUID)相關聯。不僅對於它正在構建的資源的ID,而且對於資源可能包含的所有引用也是如此。雖然上面的結構非常容易以這種方式解決,但我不知道它是否像友好或效率高,因爲典型的UINT32將用於性能關鍵的應用程序內的比較。雖然我有點擔心在這種情況下endianness可能會成爲一個偷偷摸摸的問題。

使用位運算符讀取/寫入數據源索引字節的方法可以更好地使用單個UINT32成員來實現此結構嗎?

涉及工會的定義是一個更好的策略嗎?

有沒有一個明顯的常見選擇,我錯過了?

+0

一種替代方法是不嘗試並將它們打包在一起,只使用兩個整數。 – Mat 2015-03-03 06:56:31

+0

不幸的是,我確實需要給定數據集中的索引的24位範圍。 – RobStone 2015-03-03 07:42:05

回答

3

可以使用bitfields定義結構:

typedef struct ResourceID { 
    unsigned int DataSourceIndex : 8; 
    unsigned int ResourceIndex : 24; 
} ResourceID; 

如果您希望能夠訪問ID爲一個32位的值,你可以使用這樣一個聯盟:

typedef union ResourceID { 
    struct 
    { 
     unsigned int DataSourceIndex : 8; 
     unsigned int ResourceIndex : 24; 
    }; 
    uint32_t ID; 
} ResourceID; 

關於線程安全性和位域,請參閱this StackOverflow question。如果這是一個問題,那就不要使用它們。

+0

在性能方面會增加什麼? (另外你剛剛把兩個「變量」放在同一個內存位置,這對線程安全有影響)。 – Mat 2015-03-03 06:48:34

+0

@Mat我不希望性能比在UINT32中存儲性能差,移動/屏蔽操作,但它更具可讀性。 – samgak 2015-03-03 06:57:49

+0

在這種結構下編寫標準比較運算符的最快方法是什麼,而不會冒着各種平臺上的未定義行爲的風險? – RobStone 2015-03-03 07:34:45