2016-11-17 2 views
5

В структурах C, можно указать другую битовую длину, чем битном по умолчанию длина типа, как это в:Можно ли использовать битовые поля в классах C++?

struct MyStruct{ 
    int myVar : 1; //Size of myVar is 1 bit (so it can take values 0 or 1 
    int myOtherVar: 4; //Size of myOtherVar is 4 bits (so it can take values 0 to 15) 
} 

Это называется битовыми полями.

Мой вопрос, если это возможно сделать это в C++ классов, например:

class MyClass{ 
    public: 
     //Some methods 
    private: 
     int m_myAttribute : 1; 
     int m_myOtherAttribute : 4; 
} 

Я искал в Интернете для этого, но все примеры, которые я нашел битовых полей, используемых Структуры, а не классы.

Я протестировал этот код и скомпилировал его просто отлично, но я хотел бы знать, действительно ли размер атрибутов заданного размера или компилятор просто проигнорировал битные поля и использовал стандартный размер int.

+1

Это не ответит на ваш вопрос, но может быть уместным: http://stackoverflow.com/questions/3319717/is-there-a-bit-equivalent-of-sizeof-in-c –

+0

Вы можете проверить его на 'sizeof() '. Кроме того, насколько я знаю, единственная разница между структурами и классами - переменная класса по умолчанию будет ** private **, переменная struct по умолчанию будет ** общедоступной **. Вы должны прочитать здесь: [http://stackoverflow.com/a/7762179/1867076] – Prometheus

+2

Классы на C++ идентичны структурам почти во всех отношениях. Разница ** ** ** - это спецификатор доступа по умолчанию (для классов - private, для structs - public) –

ответ

8

Да class может иметь элементы битового поля. В C++ нет разницы между class и struct, за исключением уровня доступа по умолчанию и типа наследования по умолчанию. Они называются типами классов. Если вы можете что-то сделать в struct, тогда вы можете сделать то же самое в class. Поскольку уровни доступа по умолчанию различны, они будут выглядеть немного иначе, но вы получите то же самое. Например

struct foo 
{ 
    int m_myAttribute : 1; 
    int m_myOtherAttribute : 4; 
    int m_myOtherOtherAttribute : 27; 
}; 

такая же, как

class bar 
{ 
public: 
    int m_myAttribute : 1; 
    int m_myOtherAttribute : 4; 
    int m_myOtherOtherAttribute : 27; 
}; 

ли к сведению, однако, что мы должны были использовать public: в классе, так как по умолчанию члены являются частными.

Теперь о размере битных полей в C++. [class.bit]/1 имеет всю необходимую информацию:

Постоянное выражение должно быть интегральным постоянным выражением со значением, большим или равным нулю. Значение интегрального постоянного выражения может быть больше, чем количество бит в представлении объекта (3.9) типа битового поля; в таких случаях дополнительные биты используются как биты заполнения и не участвуют в представлении значений (3.9) битового поля. Распределение бит-полей внутри объекта класса определено реализацией. Выравнивание битовых полей определяется реализацией. Бит-поля упаковываются в некоторую адресную единицу распределения. [Примечание: бит-поля выделяют единицы размещения на некоторых машинах, а не другие. Бит-поля назначаются справа налево на некоторых машинах, слева направо на других. -end примечание]

курсив мой

Отсюда получаем, что размер битового Фейлд будет по крайней мере, размер базового типа данных, но если вы более выделить место то, что дополнительные пространство превращается в заполнение и не используется для значения элемента битового поля.

+1

'за исключением уровня доступа по умолчанию' * и типа наследования по умолчанию *, хотя он здесь не используется. – Ruslan

+0

@ Ruslan Обновлено. – NathanOliver

+0

Когда вы говорите, что оба кода одинаковы, вы имеете в виду, что скомпилированные коды строго идентичны или только то, что они делают то же самое? –

0

Что касается качества реализации (QoI), то размер членов на самом деле является указанным размером со всеми компиляторами, о которых я знаю.

Если вы спрашиваете, должны ли размеры ДОЛЖНЫ соответствовать (в соответствии со стандартом), вы должны спросить себя, как бы вы сказали? (В стандартном соответствии.) Если вы не можете (и я не думаю, что вы можете), то в соответствии с правилом as-if компилятор может делать то, что ему нравится.

Для получения более подробной информации, смотрите раздел 9.6 C++14 standard (на самом деле n4296.)

2

Это совершенно законно в C++ использовать битовые поля с классами или структурами. Я также рекомендую этот вопрос для дальнейшего погружения в сходства и различия два: What are the differences between struct and class in C++?

И да битого размер действительно принимаются во внимание, только помните, что размер макета памяти зависит от конкретной реализация

class test { 
    int a : 3; 
    void fun() { 
     // std::cout << sizeof(a); // Illegal (*) 
     a = 5; // Warning! Implicit truncation from int to 3-bit bitfield yields -3 (2's complement) 
    } 
}; 

int main() { 
    std::cout << sizeof(test); // ABI-dependent, might be 4 bytes 
} 

(*) Позвольте мне также затронуть ваш комментарий относительно использования sizeof и битовых полей: это не разрешено использовать sizeof на glvalue обозначающей битовое поле, как в [expr.sizeof]/p1