Создание конструктора для структуры (объединения) в C ++ - PullRequest
0 голосов
/ 04 мая 2018

Каков наилучший способ создания конструктора для структуры (в которой есть член объединения, имеет ли это значение?) Для преобразования типа uint8_t в структуру?

Вот мой пример для уточнения:

struct twoSixByte
{
    union {
        uint8_t fullByte;
        struct
        {
            uint8_t twoPart : 2;
            uint8_t sixPart : 6;
        } bits;
    };
};

uint32_t extractByte(twoSixByte mixedByte){
  return mixedByte.bits.twoPart * mixedByte.bits.sixPart;
}

uint8_t tnum = 182;
print(extractByte(tnum)); // must print 2 * 54 = 108

приписка Находя из комментариев и ответов, в C ++ невозможно наказать типы для союзов.

Приведенные решения немного сложны, особенно если в коде много таких структур. Есть даже ситуации, когда байт делится на несколько битовых частей (более двух). Таким образом, без использования объединений и использования битовых наборов и сдвигаемых битов код становится очень обременительным.

Вместо этого мне удалось найти более простое решение. Я просто преобразовал тип, прежде чем передать его в функцию. Вот фиксированный код:

struct twoSixByte
    {
        union {
            uint8_t fullByte;
            struct
            {
                uint8_t twoPart : 2;
                uint8_t sixPart : 6;
            } bits;
        };
    };

    uint32_t extractByte(twoSixByte mixedByte){
      return mixedByte.bits.twoPart * mixedByte.bits.sixPart;
    }

    uint8_t tnum = 182;
    twoSixByte mixedType;
    mixedType.fullByte = tnum;
    print(extractByte(mixedByte)); // must print 2 * 54 = 108

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Вы можете избежать типов union и punning и использовать структуру с соответствующей функцией-членом. Обратите внимание, что нам не нужен конструктор, если struct рассматривается как агрегат для инициализации :

#include <cstdint>

struct twoSixByte {
    uint8_t fullByte; // no constructor needed, initializing as an aggregate
    uint32_t extractByte(){
        return ((fullByte & 0b1100'0000) >> 6) * (fullByte & 0b0011'1111);
    }
};


int main()
{
    twoSixByte tnum{182};
    auto test = tnum.extractByte(); // test == 2 * 54 == 108
}
0 голосов
/ 04 мая 2018

Если вам не нужно использовать union, не используйте его. Упростите свой класс до:

struct twoSixByte
{
   twoSixByte(uint8_t in) : twoPart((in & 0xC0) >> 6), sixPart(in & 0x3F) {}
   uint8_t twoPart : 2;
   uint8_t sixPart : 6;
};

Если необходимо получить полный байт, вы можете использовать:

uint8_t fullByte(twoSixByte mixedByte)
{
   return ((mixedByte.twoPart << 6) | mixedByte.sixPart);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...