序列化多态指针的QVector

时间:2014-09-29 09:27:56

标签: c++ qt inheritance serialization polymorphism

我有AbstractIndex定义其Item的接口以及排序和查询算法。此外,我有几个具体的意见,如下面的例子FileIndex。现在我想序列化indizes。我猜serializeIndex()有效,但我无法测试。在FileIndex::buildIndex() operator>> AbstractIndexProvider::Item被调用。我试图向下转换_index但我得到奇怪的编译时错误。使用 boost 我可以很容易地声明类型,但我想放弃boost依赖。 那么我该怎么做才能让Qt在FileIndex::buildIndex()中实现正确的课程?

class AbstractIndex
{
public:
    class Item;    
    void query(const QString &req, QVector<Item*> *res);

protected:
    virtual void buildIndex()      = 0;
    virtual void serializeIndex() const = 0;    
    QVector<Item*> _index;
};

class AbstractIndexProvider::Item
{
public:    
    QString _name;
    // Several pure virtual functions...

    // Serialization
    friend QDataStream &operator<<(QDataStream &out, AbstractIndexProvider::Item const * const item);
    friend QDataStream &operator>>(QDataStream &in, AbstractIndexProvider::Item *item);
};


/**************************************************************************/
class FileIndex : public AbstractIndexProvider
{
public:
    class Item;

protected:
    void buildIndex()           override;
    void serializeIndex() const override;
};

class FileIndex::Item : public AbstractIndexProvider::Item
{
    friend class FileIndex;

protected:
    QString _path;    
    friend QDataStream &operator<<(QDataStream &out, const FileIndex::Item &item);
    friend QDataStream &operator>>(QDataStream &in, FileIndex::Item &item);
};


/**************************************************************************/
void FileIndex::serializeIndex() const
{
    QFile file(_indexFile);
    if (file.open(QIODevice::ReadWrite| QIODevice::Text))
    {
        QDataStream stream( &file );
        stream << _index;
        return;
    }
}


/**************************************************************************/
void FileIndex::buildIndex()
{
    QFile file(_indexFile);
    if (file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QDataStream stream( &file );
        stream >> _index;  // WHAT TO DO HERE?
        return;
    }
}

2 个答案:

答案 0 :(得分:1)

stream >> _index;  // WHAT TO DO HERE?

QVector<Item*> _index;QVector,并且没有直接的二进制流方式。

QDebug可以编写QVector。如果您希望快速简便地进出文件系统或数据流,QByteArray处理得非常好。

否则,如果您想坚持使用QVector,请使用foreach或标准for循环或java样式迭代器或标准的lib样式迭代器迭代它。

您的代码可能类似于:

QDataStream stream( &file );
for(int i = 0; i< _index.size(); i++)
{
    stream << _index.at(i) << ",";
}
stream << "\n";
return;

http://qt-project.org/doc/qt-5/qlist.html#details

http://qt-project.org/doc/qt-5/containers.html

Qt中一些更复杂的继承示例可以在:Model / View Programming和Qt的Graphics View Framework中找到。

http://qt-project.org/doc/qt-5/graphicsview.html

http://qt-project.org/doc/qt-5/model-view-programming.html

http://qt-project.org/doc/qt-5/qabstractitemmodel.html

http://qt-project.org/doc/qt-5/qmodelindex.html

您还查看了QFileInfo类以及Qt文件系统查询中内置的过滤器和排序选项吗?

http://qt-project.org/doc/qt-5/qdiriterator.html

http://qt-project.org/doc/qt-5/qdir.html#entryInfoList

QFileInfoList QDir::entryInfoList(const QStringList & nameFilters, Filters filters = NoFilter, SortFlags sort = NoSort) const

希望有所帮助。

答案 1 :(得分:1)

您要实现的目标是虚拟化创建对象。在Qt中没有开箱即用的解决方案。所以,如果你不想使用boost,你应该自己实现它。

一种方法是为每个派生类添加一个类型标识符,并在某个工厂中注册类型 - 类对。序列化对象时,还应序列化其类型ID。反序列化时,首先从数据流中读取类型ID,然后使用对象工厂创建对象。

以下是一些有用的链接:

http://www.parashift.com/c++-faq/serialize-inherit-no-ptrs.html

http://www.parashift.com/c++-faq/virtual-ctors.html

Best Practice For List of Polymorphic Objects in C++