C ++:是否可以在同一字节中压缩`bool`对象?

时间:2018-12-13 00:06:55

标签: c++ memory boolean byte bit

考虑一个具有许多bool属性的类

class A
{
  bool a;
  bool b;
  bool c;
  bool d;
  bool e;
  bool f;
};

虽然每个bool对象可以用一个位表示,但是这里每个属性都需要一个字节(如果我没记错的话)。该对象将占用6个字节,而不是仅1个字节(实际上将使用6位)。原因是位不可寻址,只有字节可寻址。

要稍微压缩内存,可以使用vector<bool>bitset,然后按其索引访问属性。例如,可以将get函数编写为

bool A::get_d() {data[3];}

理想情况下,我希望能够使用InstanceOfA.d直接访问属性。可以这样做,同时确保我的所有6 bool都被压缩在同一个字节中吗?

2 个答案:

答案 0 :(得分:12)

您可以使用bitfields。与Repl.it的gcc版本4.6.3兼容。

#include <iostream>

struct Test 
{
  bool a:1;
  bool b:1;
  bool c:1;
  bool d:1;
  bool e:1;
  bool f:1;
  bool g:1;
  bool h:1;
  //bool i:1; //would increase size to 2 bytes.
};

int main()
{
  Test t;
  std::cout << sizeof(t) << std::endl;
  return 0;
}

答案 1 :(得分:0)

如果您真的很想节省空间,则应该使用bitset而不是位字段。

您可以看到this answer进行全面比较,但实际上位字段会由于结构而产生一些开销,并且编译器可能会或可能不会为了节省空间而实际上将元素打包在一起。

然而,位集是专门用于优化空间分配的,并且还提供了一些专门用于位旋转的有用功能。

从逻辑上讲,位集只是位数组,但为了节省空间而打包。您可以像这样使用它:

std::bitset<8> bacon;
bacon.set();    // 11111111
bacon.reset(1); // 11111101 Note: counts index from the right

std::bitset<4> fancy (std::string("1111"));
fancy[1] = 0;      // 1101 Note: counts index from the right
fancy.test(1) == 0 // true