避免多个布尔值的优雅方式

Elegant way to avoid multiple booleans?

本文关键字:方式 布尔值      更新时间:2023-10-16

在我的小型GUI库中,不同的东西可能会导致Widget变得不可见。

  1. 窗户可能会被折叠。所有子项都必须递归地变为不可见
  2. 用户可以手动隐藏小部件
  3. 小部件可能会被"排除在外"。想象一个"快门"列表框:只有按下列表框按钮时,快门及其内容才会显示

这是我目前的解决方案:

class Widget { 
    // ...
    bool collapsed;
    bool hidden;
    bool excluded;
    public:
        bool isVisible() { return !collapsed && !hidden && !excluded; }
        void hide() { hidden = true; }
        void show() { hidden = false; }
    // ...
};

我不喜欢用三个布尔值来表示相同的东西。

我考虑过使用int:

class Widget {
    int hiddenLevel{0};
    bool isVisible() { return hiddenLevel == 0; }
    void hide() { ++hiddenLevel; }
    void show() { --hiddenLevel; }
};

但是用户可能会意外地调用hide()两次。


有没有一种优雅的方法可以避免基本上做相同事情的变量重复?我不在乎小部件是collapsedhidden还是excluded,我只想知道它是否可见,并恢复折叠、隐藏或排除它的效果。

我不喜欢用三个布尔值来表示相同的东西。

正如你自己所说,这不是"一回事"。这三个条件都是独立的。

在我看来,你采取了正确的方法,isVisible()看起来是应该的。

使用枚举来表示窗口的状态:

enum window_state
{
    OPENED,
    CLOSED,
    COLAPSED,
    MINIMIZED,
    ...
};

请注意,这正是您对"int solution"所做的,也是枚举的设计目的。

所以你的实现可能是这样的:

class Widget { 
    // ...
    window_state current_state;
public:
    bool isVisible() const
    { 
        return current_state != window_state::CLOSED &&
               current_state != window_state::MINIMIZED; 
    }
    void hide() { current_state = window_state::CLOSED;  }
    void show() { current_state = window_state::OPPENED; }
    // etc, etc...
};

不要浪费这些位!你只需要三个,所以让我们丢掉32分中的24分(可能)。现在,在C++14中,它就像一个tada一样简单,tada:

char hiddenLevelStoredAsACharacter;
hiddenLevelStoredAsACharacter |= 0b00000001;

或者对于排除,如何:

hiddenLevelStoredAsACharacter |= 0b00000010;

如果这不起作用,可能有一种方法可以使用模板来完成。