Название: Наследовать QFont,QColor + контструкторы копирования
Отправлено: Fregloin от Ноябрь 16, 2011, 17:42
Привет. Возникла необходимость наследования классов QFont,QColor, таким образом, что бы они могли сериализоваться в XML. Суть: есть класс сериализатор, в котором обїявлены виртуальные методы импорта(специфичная загрузка) загрузки и сохранения данных их XML документа. Для названия нод, в которых будет храниться данные об объекте служит QString serialisationName (и importName для импорта). Привожу исходники: Класс "Сериализатор" #ifndef CSERIALISATIONOBJECT_H #define CSERIALISATIONOBJECT_H
#include <QDomDocument> #include <QDomElement>
class CXMLSerialisationObject { protected:
QString fimportNodeName; QString fserialisationNodeName;
public:
CXMLSerialisationObject();
QString importNodeName() const {return fimportNodeName;} QString serialisationNodeName() const {return fserialisationNodeName;} void setImportNodeName(QString Name); void setSerialisationNodeName(QString Name);
virtual void importFromXMLStream(QDomDocument * doc, QDomElement * node){} virtual void loadFromXMLStream(QDomDocument * doc, QDomElement * node)=0; virtual void saveToXMLStream(QDomDocument * doc, QDomElement * node)=0;
}; #endif // CSERIALISATIONOBJECT_H
#include "cserialisationobject.h"
CXMLSerialisationObject::CXMLSerialisationObject() {
}
void CXMLSerialisationObject::setImportNodeName(QString Name) { fimportNodeName = Name; }
void CXMLSerialisationObject::setSerialisationNodeName(QString Name) { fserialisationNodeName = Name; }
Мой наследуемый класс QColor #ifndef QEXCOLOR_H #define QEXCOLOR_H
#include <QColor> #include "cserialisationobject.h"
class QExColor : public QColor , public CXMLSerialisationObject { Q_INTERFACES(QColor)
public:
QExColor(); QExColor(Qt::GlobalColor color); QExColor(int r, int g, int b, int a = 255); QExColor(QRgb rgb); QExColor(const QString& name); QExColor(const char *name); QExColor(const QColor &color); QExColor(Spec spec);
void importFromXMLStream(QDomDocument *doc, QDomElement *node); void loadFromXMLStream(QDomDocument *doc, QDomElement *node); void saveToXMLStream(QDomDocument *doc, QDomElement *node); /* QExColor &operator=(const Qt::GlobalColor & color) { QString _import = this->importNodeName(); QString _serial = this->serialisationNodeName(); *this = QColor(color); this->setImportNodeName(_import); this->setSerialisationNodeName(_serial); return *this; }
QExColor &operator=(const QColor & color) { QString _import = this->importNodeName(); QString _serial = this->serialisationNodeName(); *this = color; this->setImportNodeName(_import); this->setSerialisationNodeName(_serial); return *this; }
QExColor &operator=(const QExColor & color) { QString _import = this->importNodeName(); QString _serial = this->serialisationNodeName(); *this = color; this->setImportNodeName(_import); this->setSerialisationNodeName(_serial); return *this; } */ };
#endif // QEXCOLOR_H
#include "genutils.h" #include "qexcolor.h"
QExColor::QExColor(): QColor(), CXMLSerialisationObject() {
}
QExColor::QExColor(Qt::GlobalColor color): QColor(color), CXMLSerialisationObject(this) { QString _import = importNodeName(); QString _serial = serialisationNodeName(); }
QExColor::QExColor(int r, int g, int b, int a): QColor(r,g,b,a), CXMLSerialisationObject() {
}
QExColor::QExColor(QRgb rgb): QColor(rgb), CXMLSerialisationObject() {
}
QExColor::QExColor(const QString& name): QColor(name), CXMLSerialisationObject() {
}
QExColor::QExColor(const char *name): QColor(name), CXMLSerialisationObject() {
}
QExColor::QExColor(const QColor &color): QColor(color), CXMLSerialisationObject() {
}
QExColor::QExColor(Spec spec): QColor(spec), CXMLSerialisationObject() {
}
void QExColor::importFromXMLStream(QDomDocument * /* doc */, QDomElement *node) { if(fimportNodeName.isEmpty()) return; QDomElement colorNode = node->firstChildElement(fimportNodeName); if(!colorNode.isNull()) { bool _ok; uint32_t rawColor = colorNode.attribute("Value","0").toULong(&_ok); setRed((rawColor & 0x000000FF)); setGreen((rawColor & 0x0000FF00)>>8); setBlue((rawColor & 0x00FF0000)>>16); setAlpha((rawColor & 0xFF000000)>>24); } }
void QExColor::loadFromXMLStream(QDomDocument * /* doc */, QDomElement *node) { if(fserialisationNodeName.isEmpty()) return; QDomElement colorNode = node->firstChildElement(fserialisationNodeName); if(!colorNode.isNull()) { uint32_t rawColor = 0; hexToInt(colorNode.attribute("Value","0xFF000000"),rawColor); setRed((rawColor & 0x000000FF)); setGreen((rawColor & 0x0000FF00)>>8); setBlue((rawColor & 0x00FF0000)>>16); setAlpha((rawColor & 0xFF000000)>>24); } }
void QExColor::saveToXMLStream(QDomDocument *doc, QDomElement *node) { if(fserialisationNodeName.isEmpty()) return; QDomElement colorNode = doc->createElement(fserialisationNodeName); uint32_t rawColor = makeUIntFromColor(this); colorNode.setAttribute("Value",intToHex(rawColor)); node->appendChild(colorNode); }
Данные сохраняются, загружаются нормально. Но например при операции присванивания QExColor color; color.setSerialisationName("MyColor"); //здесь присвоили имя ноды, в которую будет сериализовать ... color = Qt::gray; //здесь serialisationNode обнулятеся. Я так понял проблема в том, что в конструкторе копирования QExColor єти данные обнуляются (операторы присваивания которые закоментил тут не срабатывают). Как сделать так, что бы при присваивании переменной QExColor значения Qt::GlobalColor или QColor переменные класса CXMLSerialisationObject не затрагивались???
Название: Re: Наследовать QFont,QColor + контструкторы копирования
Отправлено: Akon от Ноябрь 16, 2011, 19:52
Имхо, плохой дизайн. Классы, наподобие QFont или QColor - это классы-значения, про такие классы можно также сказать, что они "законченные" (final, sealed), т.е. они не проектировались под наследование.
Сделайте внешний сериализатор, который возьмет на себя аспект сериализации. Например, для многих классов Qt есть поддержка вывода отладочной информации (qDebug() << QFont() << QColor() << ...), реализуемая внешним компонентом (qDebug()).
Название: Re: Наследовать QFont,QColor + контструкторы копирования
Отправлено: Авварон от Ноябрь 17, 2011, 10:49
Имхо, плохой дизайн. Классы, наподобие QFont или QColor - это классы-значения, про такие классы можно также сказать, что они "законченные" (final, sealed), т.е. они не проектировались под наследование.
Сделайте внешний сериализатор, который возьмет на себя аспект сериализации. Например, для многих классов Qt есть поддержка вывода отладочной информации (qDebug() << QFont() << QColor() << ...), реализуемая внешним компонентом (qDebug()).
Не имхо, а ужасный. Классы с иерархией наследования, без виртуального деструктора, да еще с конструктором копирования использовать крайне небезопасно.
|