c++ - 枚举位域容器类

标签 c++ enums bit-fields bitflags

我正在尝试编写一个小类以更好地理解 C++ 中的位标志。但是有些事情没有解决。它打印错误的值。哪里有问题?我是否误解了如何添加标志?或者检查位域是否有它们?

代码如下:

#include <iostream>

enum flag
{
    A = 1, B = 2, C = 4
};

class Holder
{
public:
    Holder() : m_flags(A) {}
    ~Holder() {}

    void add_flag(flag f) { m_flags |= f; }
    bool has_flag(flag f) { return ((m_flags&f)==f); }
    void remove_flag(flag f) 
    {
        unsigned int flags = 0;
        for (int i = 1; i<=(int)C; i *= 2)
        {
            if ((flag)i!=f && has_flag(f))
                flags |= f;
        }
        m_flags = flags;
    }

    void print()
    {
        std::cout << "flags are now: " << m_flags << " | holding: "; 
        for (int i = 1; i<=(int)C; i *= 2)
        {
            if (has_flag((flag)i))
                std::cout << i << " ";
        }
        std::cout << std::endl;
    }

private:
    unsigned int m_flags;
};

int main()
{
    Holder h;
    h.print(); // should print 1

    h.add_flag(B);
    h.print(); // should print 1 2

    h.remove_flag(A);
    h.print(); // should print 2

    h.add_flag(C);
    h.print(); // should print 2 4

    h.remove_flag(B);
    h.print(); // should print 4
}

程序输出:

flags are now: 1 | holding: 1 
flags are now: 3 | holding: 1 2 
flags are now: 1 | holding: 1 
flags are now: 5 | holding: 1 4 
flags are now: 0 | holding: 

最佳答案

就我个人而言,我会使用 std::vector< bool > 来处理标志,因为它是一种将 bool 值打包成位的特化。

但是:

我觉得你的删除标志有点复杂,试试这个

void remove_flag( flag f ) 
{
   if ( has_flag( f ) == true )
   {
      m_flags ^= f;   // toggle the bit leaving all other unchanged
   } 
}

编辑: 有评论问我为什么不做 m_flags &= ~f。我把这个问题当作“学习者”问题而不是优化问题。我展示了如何使他的代码正确而不是快速。

关于c++ - 枚举位域容器类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/524028/

相关文章:

c++ - 将枚举类型转换为整数,反之亦然

ios - 如何在UITableView中正确使用Enum?

c++ - 将模板类的对象传递给另一个类的构造函数

java - 映射一组枚举 - Hibernate

ios - 更新/更改 Swift 中枚举的 rawValue

c - 将 uint8_t 中的位地址作为结构体的成员

c++ - 字段并集和结构并集之间的区别

c++ - 结构位域最大大小(C99,C++)

C++:string = NULL 给出 SEGFAULT 11?

c++ - 等待线程直到条件发生