使用枚举使用按位参数组合的最佳做法?

时间:2011-04-25 16:01:59

标签: c++ enums state bitwise-operators

我正在实现一个生活在屏幕上的视图。根据以下配置参数,只要屏幕尺寸发生变化,视图就会定位并调整大小。

enum DLViewLayout
{
    DLViewLayoutSolo = 1,
    DLViewLayoutDual = 2
};
enum DLViewFixedHorizontalProperty
{
    DLViewFixedHorizontalPropertyWidth = 4, // View margins scale with the screen width.
    DLViewFixedHorizontalPropertyMargin = 8 // View width scales with the screen width.
};
enum DLViewFixedVerticalProperty
{
    DLViewFixedVerticalPropertyHeight = 16,
    DLViewFixedVerticalPropertyMargin = 32
};
enum DLViewHorizonalAlignment
{
    DLViewHorizonalAlignmentLeft = 64,
    DLViewHorizonalAlignmentCenter = 128,
    DLViewHorizonalAlignmentRight = 256
};
enum DLViewVerticalAlignment
{
    DLViewVerticalAlignmentTop = 512,
    DLViewVerticalAlignmentMiddle = 1024,
    DLViewVerticalAlignmentBottom = 2048
};

我想知道在什么情况下按位OR组合枚举值以传递视图状态是有意义的。

int viewState = DLViewLayoutSolo | DLViewFixedHorizontalPropertyWidth | DLViewFixedVerticalPropertyMargin | DLViewHorizonalAlignmentCenter | DLViewVerticalAlignmentMiddle;  
// viewState = 1189

我希望该类的用户配置所有参数。我该如何强制执行此操作?

在课程中,我可以通过按位AND组合状态来检索单个设置。

if (viewState & DLViewLayoutSolo)
{
  // Set up solo view layout.
}
else if (viewState & DLViewLayoutDual)
{
  // Set up dual view layout.
}

2 个答案:

答案 0 :(得分:3)

您想使用来自不同枚举的值组合标志吗?

永远不会成为最佳做法,事实上,我从未在任何练习中看到它,不管是好还是坏。这样,除了其他问题之外,利用暴露这些标志的属性的实例的任何元素必须知道或者预期知道它是来自这些不同enum类型的值的合并。

由于这些值会逐渐提升,为什么不简单地使用一个由所有成员组成的恰当命名的枚举?

另外,如果我们在这里谈论.NET(尽管是合法的,但是冒号告诉我可能没有),这些enum类型应该用[Flags]属性进行修饰,但仍然只是合并相同enum类型的值。

答案 1 :(得分:1)

听起来好像你想要的值的字段取决于每个子条件的状态:

enum DLViewLayout
{
    DLViewLayoutSolo,
    DLViewLayoutDual
};
enum DLViewFixedHorizontalProperty
{
    DLViewFixedHorizontalPropertyWidth, // View margins scale with the screen width.
    DLViewFixedHorizontalPropertyMargin // View width scales with the screen width.
};
enum DLViewFixedVerticalProperty
{
    DLViewFixedVerticalPropertyHeight,
    DLViewFixedVerticalPropertyMargin
};
enum DLViewHorizonalAlignment
{
    DLViewHorizonalAlignmentLeft,
    DLViewHorizonalAlignmentCenter,
    DLViewHorizonalAlignmentRight
};
enum DLViewVerticalAlignment
{
    DLViewVerticalAlignmentTop,
    DLViewVerticalAlignmentMiddle,
    DLViewVerticalAlignmentBottom
};

struct DLView {
    DLViewLayout layout;
    DLViewFixedHorizontalProperty fixed_horizontal;
    DLViewFixedVerticalProperty fixed_vertical;
    DLViewHorizonalAlignment horizontal;
    DLViewVerticalAlignment vertical;
};

// ...
DLView viewState;
// ...
if ( viewState.layout == DLViewLayoutSolo ) { ... }
else if ( viewState.layout == DLViewLayoutDual ) { ... }
}

/// repeat per field

如果您担心内存消耗,并且有正当理由,那么您可以使用非可移植位字段构造:

struct DLView {
    DLViewLayout layout : 1;
    DLViewFixedHorizontalProperty fixed_horizontal : 1;
    DLViewFixedVerticalProperty fixed_vertical : 1;
    DLViewHorizonalAlignment horizontal : 2;
    DLViewVerticalAlignment vertical : 2;
};