2014-09-29 87 views
0

我有一個AbstractIndex定義其Item的接口和排序和查詢算法。此外,我有幾個具體的指標,如下面的示例FileIndex。現在我想序列化指標。我想serializeIndex()的作品,但我無法測試它。在FileIndex::buildIndex()operator>>AbstractIndexProvider::Item被調用。我試圖downcast _index但我得到奇怪的編譯時錯誤。使用boost我可以輕鬆聲明類型,但我想放棄boost依賴。 那麼我該怎麼做才能讓Qt在FileIndex::buildIndex()上實現正確的類?多態指針的序列化QVector

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; 
    } 
} 

回答

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

QVector<Item*> _index;QVector,沒有二進制流的一個直接的方式。

QDebug有辦法寫一個QVector。如果你想要一個快速簡便的文件系統或數據流,QByteArray處理得很好。

否則,如果你想堅持QVector,通過它要麼foreach或標準for環或Java風格的迭代或標準庫風格的迭代循環。

您的代碼可能看起來像:模型/視圖編程和Qt的:

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中繼承的更復雜的例子中可以找到圖形視圖框架。

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 

希望有所幫助。

+0

所以,你到底有什麼選擇了這樣做,它會工作嗎? – phyatt 2014-10-21 19:10:41

1

你試圖實現的是virtualize創建你的對象。 Qt中沒有開箱即用的解決方案。所以,如果你不想使用boost,你應該自己實現它。

一種方法是爲每個派生類添加類型標識符,並在某些工廠中註冊類型對。當你序列化你的對象時,你還應該序列化它們的類型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++