Russian Qt Forum
Октябрь 02, 2024, 19:23 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Наследовать QFont,QColor + контструкторы копирования  (Прочитано 2508 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Ноябрь 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 не затрагивались???
Записан
Akon
Гость
« Ответ #1 : Ноябрь 16, 2011, 19:52 »

Имхо, плохой дизайн. Классы, наподобие QFont или QColor - это классы-значения, про такие классы можно также сказать, что они "законченные" (final, sealed), т.е. они не проектировались под наследование.

Сделайте внешний сериализатор, который возьмет на себя аспект сериализации. Например, для многих классов Qt есть поддержка вывода отладочной информации (qDebug() << QFont() << QColor() << ...), реализуемая внешним компонентом (qDebug()).
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #2 : Ноябрь 17, 2011, 10:49 »

Имхо, плохой дизайн. Классы, наподобие QFont или QColor - это классы-значения, про такие классы можно также сказать, что они "законченные" (final, sealed), т.е. они не проектировались под наследование.

Сделайте внешний сериализатор, который возьмет на себя аспект сериализации. Например, для многих классов Qt есть поддержка вывода отладочной информации (qDebug() << QFont() << QColor() << ...), реализуемая внешним компонентом (qDebug()).


Не имхо, а ужасный. Классы с иерархией наследования, без виртуального деструктора, да еще с конструктором копирования использовать крайне небезопасно.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.129 секунд. Запросов: 22.