Как разобрать структуру в объединении в CPP? - PullRequest
1 голос
/ 10 февраля 2012

У меня есть объединение и enum, например:

typedef union{
    Home   HomeInfo;        
    Office OfficeInfo;          
} Info;

typedef enum{                               
    eHOME,  
    eOFFICE

} InfoType;

Home и Office - это другие структуры.

У меня есть другая функция, прототип которой

void SetInfo(InfoType, Info);

Во время вызова функции, если InfoType равно eHOME, я бы создал объект Info, Info info; и заполнил бы HomeInfo details info.HomeInfo и вызвал бы

SetInfo(eHONE, info);

SetInfoопределение:

SetInfo(InfoType infotype, Info info)
{
    if (eHOME == infotype)
    {
        // get the details from info.HomeInfo structure
         }
         else if(eOFFICE == infotype)
         {
            // get the details from info.OffiiceInfo structure
         }
}

Как получить недопустимый случай, если я передаю eHOME как InfoType и передаю данные OfficeInfo?Хотя в то время я получал детали HomeInfo, в нем есть ненужные значения, поэтому ошибка не появляется.Можно ли проверить, что это за структура после InfoType проверки?

Ответы [ 4 ]

0 голосов
/ 10 февраля 2012

Этот вид проверки возможен. info по сути не является Home или Office. Это блок байтов, который вы можете интерпретировать как один, потому что это объединение.

Это не похоже на хорошее использование для союза вообще. Вместо этого Office и Home должны наследоваться от общего родителя, скажем, Info. Тогда SetInfo должен взять ссылку на Info, как это:

void SetInfo(Info &myInfo);

И вам понадобится какой-нибудь фабричный метод, который знает, нужно ли ему передавать экземпляр Home или Office.

0 голосов
/ 10 февраля 2012

void SetInfo (InfoType a, Info b);

Возможно, вы можете привести & b к Home *, а затем жестко закодировать первую «переменную класса» для Home и Office на символ, который вы можете обнаружить иинициализировать определенными значениями для легкого обнаружения.

Имеет ли это какой-либо смысл ,,, ...

0 голосов
/ 10 февраля 2012

В этом случае вы должны убедиться, что Info и InfoType согласованы при каждом вызове SetInfo.

Если вы намеревались вызвать SetInfo с несовместимыми Info и InfoType, например:

InfoType type = eHOME;
Info info;
info.OfficeInfo.xxx = xxx;
SetInfo(type, info);

По сути, как объединение, вы не можете различить, является ли информация OfficeInfo или HomeInfo, без дополнительной информации о 2 типах.

0 голосов
/ 10 февраля 2012

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

enum InfoType
{
    eHome,
    eOffice,
};

class Info
{
public:
    InfoType type() const { return type_; }

protected:
    Info(InfoType t) : type_(t) {}

private:
    InfoType type_;
};

class HomeInfo : public Info
{
public:
    HomeInfo() : Info(eHome) {}
};

class OfficeInfo : public Info
{
public:
    OfficeInfo() : Info(eOffice) {}
};

Теперь SetInfo Функция так же просто, как:

void SetInfo(Info* info)
{
    if (info->type() == eHome)
    {
        HomeInfo* hi = (HomeInfo*)info;
        // ...
    }
    else if (info->type() == eOffice)
    {
        OfficeInfo* oi = (OfficeInfo*)info;
        // ...
    }
}
...