13.8. Битовое поле – член, экономящий память
13.8. Битовое поле – член, экономящий память
Для хранения заданного числа битов можно объявить член класса специального вида, называемый битовым полем. Он должен иметь целый тип данных, со знаком или без знака:
class File {
// ...
unsigned int modified : 1; // битовое поле
};
После идентификатора битового поля следует двоеточие, а за ним – константное выражение, задающее число битов. К примеру, modified – это поле из одного бита.
Битовые поля, определенные в теле класса подряд, по возможности упаковываются в соседние биты одного целого числа, делая хранение объекта более компактным. Так, в следующем объявлении пять битовых полей будут содержаться в одном числе типа unsigned int, ассоциированном с первым полем mode:
typedef unsigned int Bit;
class File {
public:
Bit mode: 2;
Bit modified: 1;
Bit prot_owner: 3;
Bit prot_group: 3;
Bit prot_world: 3;
// ...
};
Доступ к битовому полю осуществляется так же, как к прочим членам класса. Скажем, к битовому полю, являющемуся закрытым членом класса, можно обратиться лишь из функций-членов и друзей этого класса:
void File::write()
{
modified = 1;
// ...
}
void File::close()
{
if ( modified )
// ... сохранить содержимое
}
Вот простой пример использования битового поля длиной больше 1 (примененные здесь побитовые операции рассматривались в разделе 4.11):
enum { READ = 01, WRITE = 02 }; // режимы открытия файла
int main() {
File myFile;
myFile.mode |= READ;
if ( myFile.mode & READ )
cout "myFile.mode is set to READ ";
}
Обычно для проверки значения битового поля-члена определяются встроенные функции-члены. Допустим, в классе File можно ввести члены isRead() и isWrite():
inline int File::isRead() { return mode & READ; }
inline int File::isWrite() { return mode & WRITE; }
if ( myFile.isRead() ) /* ... */
С помощью таких функций-членов битовые поля можно сделать закрытыми членами класса File.
К битовому полю нельзя применять оператор взятия адреса (&), поэтому не может быть и указателя на подобные поля-члены. Кроме того, полю запрещено быть статическим членом.
В стандартной библиотеке C++ имеется шаблон класса bitset, который облегчает манипуляции с битовыми множествами. Мы рекомендуем использовать его вместо битовых полей. (Шаблон класса bitset и определенные в нем операции рассматривались в разделе 4.12.)
Упражнение 13.17
Перепишите примеры из этого подраздела так, чтобы в классе File вместо объявления и прямого манипулирования битовыми полями использовался класс bitset и его операторы.