2015-03-03 30 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