Название: "Виртуальные" члены класса?
Отправлено: Fregloin от Август 01, 2011, 14:31
Есть базовый класс модуля устройства, к примеру CGenericModule. #ifndef CGENERICMODULE_H #define CGENERICMODULE_H
class CEC; class QGenericModule;
class CGenericModule { protected: CEC * fparentEC; //владелец QGenericModule * fmodule; //связанный модуль на view virtual void attachToGUIModule()=0; virtual void detachFromGUIModule()=0; public: CGenericModule(CEC * ParentEC); QGenericModule * module(){return fmodule;} void setModule(QGenericModule * AModule); virtual void update(){} virtual void unlinkModule()=0; };
#endif // CGENERICMODULE_H
От него наследуются несколько дочерних классов, как то - модуль базовый ввода/вывода (CIOModule), модуль питания (CPowerModule), модуль охлаждения (CCooler) и т.п. В классе CGenericModule член QGenericModule * fmodule; хранит указатель на GUI объект, который отображается на сцене (иерархия GUI объектов похожа). Но в дочерних классах, мне нужно хранить fmodule уже типа GUI объекта (т.е. не QGenericModule, а QIOModule, QPowerModule, QCooler...). Как можно добиться "виртуальности" члена fmodule, что бы в каждом классе он соотвествовал нужному типу (т.е. грубо перегрузить его тип). Раньше я делал так, в каждй дочерний класс добавлял новый приватный член уже нужного типа, а его значение приводил через dynamic_cast к нужному типу. Является ли такой подход единственным? или задействовать шаблоны? хотя думаю могут возникнуть проблемы...
Название: Re: "Виртуальные" члены класса?
Отправлено: Fregloin от Август 01, 2011, 14:35
вот как делаю сейчас: class CIOModule : public CGenericModule { protected: bool speedChanged; bool stateChanged; bool countChanged; void attachToGUIModule(); void detachFromGUIModule(); QIOModule * fioModule; public: CIOModule(CEC * ParentEC); uint8_t OldState; uint16_t OldSpeed; uint16_t OldCount; uint8_t* StatePtr; uint16_t* SpeedPtr; uint16_t* CountPtr; void update(); void unlinkModule(); };
void CIOModule::attachToGUIModule() { fioModule = dynamic_cast<QIOModule*>(fmodule); if(fioModule) { fioModule->beginUpdate(); fioModule->setCurrentStateColor(Qt::white); fioModule->setSpeedText(linked); fioModule->setCountText(linked); fioModule->endUpdate(); } }
void CIOModule::update() { if(!fioModule) return;
speedChanged = countChanged = stateChanged = false;
if(StatePtr && OldState!=*StatePtr) { OldState = *StatePtr; stateChanged = true; }
if(SpeedPtr && OldSpeed!=*SpeedPtr) { OldSpeed = *SpeedPtr; speedChanged = true; }
if(CountPtr && OldCount!=*CountPtr) { OldCount = *CountPtr; countChanged = true; }
if(stateChanged || countChanged || speedChanged) { fioModule->beginUpdate();
if(stateChanged) { if(OldState==0) fioModule->setCurrentStateColor(lightRed); else fioModule->setCurrentStateColor(lightGreen); }
if(speedChanged) fioModule->setSpeedText(QString::number(OldSpeed)); if(countChanged) fioModule->setCountText(QString::number(OldCount));
fioModule->endUpdate(); } }
Название: Re: "Виртуальные" члены класса?
Отправлено: Fregloin от Август 01, 2011, 14:37
т.е. не хочется использовать часто dynamic_cast во всех методах класса CIODevice, или другого не дано?
Название: Re: "Виртуальные" члены класса?
Отправлено: SASA от Август 01, 2011, 14:42
А зачем базовый класс содержит QGenericModule * fmodule?
Название: Re: "Виртуальные" члены класса?
Отправлено: Fregloin от Август 01, 2011, 14:54
#include <stddef.h> #include "cgenericmodule.h" #include "qgenericmodule.h" #include "qiomodule.h"
CGenericModule::CGenericModule(CEC * ParentEC) { fparentEC = ParentEC; fmodule = NULL; }
void CGenericModule::setModule(QGenericModule * AModule) { if(fmodule!=AModule) { if(!AModule) { detachFromGUIModule(); } fmodule = AModule; if(fmodule) { attachToGUIModule(); } } }
изза функции setModule(), в которой я устанавливаю указатель на новый GUI объект, вызывая при этом виртуальные функции привязок для каждого отдельного класса, а fmodule содержит указатель на текущий GUI объект.
Название: Re: "Виртуальные" члены класса?
Отправлено: m_ax от Август 01, 2011, 15:21
Чем не устраивает вариант оформить CGenericModule в виде шаблона? C++ (Qt) template <class TModule> class CGenericModule { protected: CEC * fparentEC; //владелец TModule * fmodule; //связанный модуль на view virtual void attachToGUIModule()=0; virtual void detachFromGUIModule()=0; public: CGenericModule(CEC * ParentEC); TModule * module(){return fmodule;} void setModule(TModule * AModule); virtual void update(){} virtual void unlinkModule()=0; }; class CIOModule : public CGenericModule<QIOModule> { ... };
Название: Re: "Виртуальные" члены класса?
Отправлено: Igors от Август 01, 2011, 16:31
void CIOModule::attachToGUIModule() { fioModule = dynamic_cast<QIOModule*>(fmodule); if(fioModule) { fioModule->beginUpdate(); fioModule->setCurrentStateColor(Qt::white); fioModule->setSpeedText(linked); fioModule->setCountText(linked); fioModule->endUpdate(); } }
Явно нехорошо, т.к. CIOModule знает все-все о QIOModule (хотя не порожден от него). Также то что в скобках смотрится как метод. Почему бы для начала не пойти по простейшему пути: добавить все возможные вызовы в виртуалы базового класса. Тогда бы выглядело так C++ (Qt) void CIOModule::attachToGUIModule() { if (fioModule)) fioModule->attachAction(); // возможно с параметрами }
Название: Re: "Виртуальные" члены класса?
Отправлено: SASA от Август 02, 2011, 12:23
Я бы делал в дочерних классах сделал функции типа QIOModule * getIOModule(); а в ней динамик каст или qobject_cast.
|