Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [qt4] Сериализация пользовательского объекта


Автор: BiTOk 8.12.2011, 21:59
Доброе время суток. Потребовалось сериализовать объект на основе моего класса. Класс такого вида:

Код

class ExpertSystem
{
public:
    ExpertSystem();
    ExpertSystem(const ExpertSystem &expert_system);
    ~ExpertSystem();
...
private:
    RulesList rules_list_;
    VariableList variable_list_;
    DomainList domains_list_;
    QString name_;

    QString goal_;
};


где RulesList, VariableList, DomainList имеют такой вид:
Код

class RulesList : public QVector<Rule>
{
public:
    explicit RulesList();

    int indexOf(QString rule_name);
private:
}


Требуется упаковать объект класса ExpertSystem в файл и распаковать его из файла с минимальными затратами времени на реализацию этих действий. Сам попробовал зарегистрировать свой тип в метаобъектной системе Q_DECLARE_METATYPE(ExpertSystem), реализовать операторы << и >>, где в QDataStream просто совал rules_list_, variable_list_, domains_list_ и вызвать qRegisterMetaTypeStreamOperators для каждого из этих классов, но компилятор кричит на то, что не хватает реализации << и >> для RulesList, VariableList, DomainList. Дальше биться и пытаться реализовать это всё для каждого из озвученных классов не стал. Как лучше поступить - реализовать всё это для каждого из классов (странно, почему эти операторы не унаследовались от QVector) или есть иные, более быстрые пути для решения вопроса?

Автор: boostcoder 8.12.2011, 22:03
Цитата(BiTOk @  8.12.2011,  21:59 Найти цитируемый пост)
Как лучше поступить - реализовать всё это для каждого из классов (странно, почему эти операторы не унаследовались от QVector) или есть иные, более быстрые пути для решения вопроса?

да. использовать http://www.boost.org/doc/libs/1_48_0/libs/serialization/doc/index.html smile 

Автор: bsa 8.12.2011, 22:26
Цитата(boostcoder @  8.12.2011,  23:03 Найти цитируемый пост)
да. использовать boost.serialization

Ты дурного не посоветуешь. ТС останется только реализовать сериализацию стандартных контейнеров Qt - фигня вопрос.  smile

Добавлено через 6 минут и 24 секунды
BiTOk, начну с того, что наследовался от QVector ты зря. Такие классы лучше не наследовать. Ну или хотя бы приватно. Они не предназначены для этого.
Переопредели эти методы. Получится не сильно длиннее, чем при использовании boost.serialization.

Автор: boostcoder 8.12.2011, 22:46
Цитата(bsa @  8.12.2011,  22:26 Найти цитируемый пост)
ТС останется только реализовать сериализацию стандартных контейнеров Qt - фигня вопрос.

что-то тут не так..
"стандартные контейнеры Qt" - это стёб, я полагаю? smile 
ибо какие же они стандартные, если их не может сериализовать сериализатор, сериализующий стандартные контейнеры? кто солгал?

Автор: bsa 8.12.2011, 23:09
Цитата(boostcoder @  8.12.2011,  23:46 Найти цитируемый пост)
ибо какие же они стандартные, если их не может сериализовать сериализатор, сериализующий стандартные контейнеры? кто солгал?

стандартный сериализатор их сериализовать может. Он не может сериализовать наследников этих классов. Потому что не знает о них.

Автор: boostcoder 9.12.2011, 00:00
Цитата(bsa @  8.12.2011,  23:09 Найти цитируемый пост)
стандартный сериализатор их сериализовать может

boost.serialization умеет сериализовать QVector? smile 

Автор: newbee 9.12.2011, 00:27
Такое наследование от кувектора - просто идиотизм. Определи операцию преобразования QString->Rule и будет тебе indexOf по строке, аналогично с двумя другими типами.

Если нужно быстро и сердито, а Rule и два других типа простые, держи самый джедайский метод: вытаскивай данные вектора через QVector::data() и напрямую сливай их в файл.

Автор: BiTOk 9.12.2011, 07:45
Цитата(newbee @ 9.12.2011,  00:27)
Такое наследование от кувектора - просто идиотизм. Определи операцию преобразования QString->Rule и будет тебе indexOf по строке, аналогично с двумя другими типами.

Если нужно быстро и сердито, а Rule и два других типа простые, держи самый джедайский метод: вытаскивай данные вектора через QVector::data() и напрямую сливай их в файл.

К сожалению, Rule и остальные классы сложные, там несколько полей, хоть и элементарных. Стало быть собрать просто так объекты не удастся, надо писать код сериализации?

Автор: bsa 9.12.2011, 09:55
Цитата(BiTOk @  9.12.2011,  08:45 Найти цитируемый пост)
К сожалению, Rule и остальные классы сложные, там несколько полей, хоть и элементарных. Стало быть собрать просто так объекты не удастся, надо писать код сериализации? 

да.
Цитата(boostcoder @  9.12.2011,  01:00 Найти цитируемый пост)
boost.serialization умеет сериализовать QVector?

надеюсь, ты тупишь только из-за недосыпа... когда речь идет о Qt, то под стандартными подразумеваются средства Qt. Естественно в Qt есть свой сериализатор, который умеет работать с контейнерами входящими в состав Qt.

Автор: boostcoder 9.12.2011, 10:38
Цитата(bsa @  9.12.2011,  09:55 Найти цитируемый пост)
под стандартными подразумеваются средства Qt

повторю. как слово "стандартный" соприкасается с куте?! smile 

зы
так и вижу ситуацию, когда bsa приходит в аптеку за аспирином, а ему говорят что стандартного аспирина нет, есть только самопальный. bsa спрашивает: "а этот самопальный, соответствует стандарту?", на что ему отвечают: "нет. он просто так же называется.". но следуя логике bsa, он его обязательно купит, и даже всем рекомендовать будет, ибо не понимает смысл слова "стандарт". страшно жить... :facepalm

Добавлено @ 10:41
Цитата(bsa @  9.12.2011,  09:55 Найти цитируемый пост)
тупишь

не исключено... но почему так долго не отпускает? smile 

Автор: newbee 9.12.2011, 14:17
Qt ведь совместим со стандартными (которые в std) алгоритмами и итераторами... Если сериализатор работает через них, то и кутешные вектора должен уметь сериализовать.

Автор: bsa 9.12.2011, 14:35
Цитата(boostcoder @  9.12.2011,  11:38 Найти цитируемый пост)
как слово "стандартный" соприкасается с куте?!

точно так же, как и слово "стандартный" со словом "сериализатор". 
Цитата(newbee @  9.12.2011,  15:17 Найти цитируемый пост)
Если сериализатор работает через них, то и кутешные вектора должен уметь сериализовать.
Работать то он работает, вот только необходимы соответствующие перегруженные методы, так как QVector это совсем не тоже самое, что и std::vector.

Автор: boostcoder 9.12.2011, 14:47
Цитата(bsa @  9.12.2011,  14:35 Найти цитируемый пост)
точно так же, как и слово "стандартный" со словом "сериализатор"

а разве сериализатор стандартный? он ведь просто умеет сериализовать стандартные контейнеры smile 

Автор: spyswamp 9.12.2011, 17:56
Модератор: Сообщение скрыто.

Автор: spyswamp 11.12.2011, 21:52
Мог бы мат просто закрыть. Лол.

Автор: Artemon 13.12.2011, 09:51
Вот пример класса, который можно записать в файл, передать по сети и т.д.
Если поля класса - тоже сложные объекты, то с ними можно поступить точно также.

Базовый класс:

Код

struct IStreamSupport
{
    // Чертпобери, чтобы объекты корректно удалялись, необъодимо чтобы деструктор был виртуальным
    virtual ~IStreamSupport(){};

    virtual QDataStream& put(QDataStream& os)const = 0;
    virtual QDataStream& get(QDataStream& is) = 0;

    friend inline QDataStream& operator<<(QDataStream& os, const IStreamSupport* b);
    friend inline QDataStream& operator>>(QDataStream& is, IStreamSupport* b);
};

inline QDataStream& operator<<(QDataStream& os, const IStreamSupport* b) 
{
    return b->put(os);
}

inline QDataStream& operator>>(QDataStream& is, IStreamSupport* b)
{
    return b->get(is);
}


Производный класс
Код

struct SServerNetworkPrivate : public IStreamSupport
{

    virtual QDataStream& put(QDataStream& os)const
    {
        SBaseServerSettings::put(os);

        os << Port;
        os << PortSecond;

        return os;
    }

    virtual QDataStream& get(QDataStream& is)
    {
        SBaseServerSettings::get(is);

        is >> Port;
        is >> PortSecond;

        return is;
    }

    int Port;    // Порт, первого канала, который прослушивает сервер
    int PortSecond; // Порт второго канала, который прослушивает сервер
};


При таком подходе можешь проводить сериализацию полиморфных классов.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)