Re: доступ к элементам структуры
От: Максим2006 Беларусь  
Дата: 29.05.07 09:46
Оценка:
Здравствуйте, bookevg, Вы писали:

B>На данный момент в нашем программном продукте при описании свойств объекта используется:

B>typedef struct tobj_status_bit
B>{
B> unsigned Sts : 1; // 0 состояние объекта: 1 — в работе; 0 — выключен
B> unsigned Rdy : 1; // 1 готовность объекта: 1 — есть; 0 -нет
B>} TObj_Status_Bit;
B>typedef union tobj_status
B>{
B> TObj_Status_Bit bReg; // побитное представление
B> unsigned int Reg; // регистровое представление
B>} TObj_Status;
B>Хотелось бы:
B>class CObj_Status
B>{
B>..
B>TObj_Status dObj_Status;
B>..
B>};
B>CObj_Status Obj_Status;
B>и при присвоении полю структуры какого-то значения выполнить еще ряд действий, т.е.:
B>Obj_Status.dObj_Status.bReg.Sts = 1 или
B>Obj_Status.dObj_Status.bReg.Rdy = 1
B>приводило к выполнению кода:
B>{
B>// действия
B>dObj_Status.bReg.Sts = 1;
B>}

Можно завести вспомогательные классы, правда тогда регистровое представление функцией нужно сделать (у меня так получилось, но возможны варианты).

    struct istatus {
        virtual void OnStatusChanged(unsigned status) = 0;
    };

    struct StatusBit
    {
        StatusBit(istatus* pStatus) : m_pStatus(pStatus) {}

        StatusBit& operator=(unsigned status)
        {
            m_pStatus->OnStatusChanged(status);
            return *this;
        }

    private:
        istatus* m_pStatus;
    };

    struct iready {
        virtual void OnReadyChanged(unsigned nReady) = 0;
    };

    struct ReadyBit
    {
        ReadyBit(iready* pReady) : m_pReady(pReady) {}

        ReadyBit& operator=(unsigned ready)
        {
            m_pReady->OnReadyChanged(ready);
            return *this;
        }

    private:
        iready* m_pReady;
    };

    struct StatusData : private istatus, private iready
    {
        StatusData() :
            Status(static_cast<istatus*>(this)),
            Ready(static_cast<iready*>(this))
        {}

        StatusBit Status;
        ReadyBit Ready;

        unsigned int Reg() const { return m_DataUnion.data; }
        unsigned int& Reg() { return m_DataUnion.data; }

    private:
        // istatus
        virtual void OnStatusChanged(unsigned status) {
            m_DataUnion.dataBit.nStatus = status;
        }

        // iready
        virtual void OnReadyChanged(unsigned ready) {
            m_DataUnion.dataBit.nReady = ready;
        };

    private:
        struct Data {
            unsigned nStatus : 1;
            unsigned nReady : 1;
        };

        union DataUnion {
            Data dataBit;
            unsigned data;
        };

        DataUnion m_DataUnion;
    };


Использовать как обычно, кроме регистра:

    StatusData DeviceBit;
    DeviceBit.Reg() = 0;
    DeviceBit.Status = 1;
    DeviceBit.Ready = 1;
    DeviceBit.Reg() = 4;
    unsigned i = DeviceBit.Reg();
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.