2012-02-26 76 views
1

我有一个类IDocument作为一些类的接口。它有一些摘要方法(virtual ... = 0)。Qt序列化,非成员QDataStream&运算符<<

我愿做这样的所有子类也必须实现序列化操作:

除了这里记录的过载流运营商,任何的Qt类,你可能想要序列化操作QDataStream会有适当的流运营商宣布为非类的成员:

我甚至不知道如何做抽象运算符,但我如何定义它非成员?

回答

2

非会员运营商是一项免费功能,几乎与任何其他免费功能一样。对于QDataStream,在operator<<会是什么样子:

QDataStream& operator<<(QDataStream& ds, SomeType const& obj) 
{ 
    // do stuff to write obj to the stream 
    return ds; 
} 

在你的情况,你可以实现你的序列化这样的(这是做的只是一种方式,也有其他人):

#include <QtCore> 

class Base { 
    public: 
     Base() {}; 
     virtual ~Base() {}; 
    public: 
     // This must be overriden by descendants to do 
     // the actual serialization I/O 
     virtual void serialize(QDataStream&) const = 0; 
}; 

class Derived: public Base { 
    QString member; 
    public: 
     Derived(QString const& str): member(str) {}; 
    public: 
     // Do all the necessary serialization for Derived in here 
     void serialize(QDataStream& ds) const { 
      ds << member; 
     } 
}; 

// This is the non-member operator<< function, valid for Base 
// and its derived types, that takes advantage of the virtual 
// serialize function. 
QDataStream& operator<<(QDataStream& ds, Base const& b) 
{ 
    b.serialize(ds); 
    return ds; 
} 

int main() 
{ 
    Derived d("hello"); 

    QFile file("file.out"); 
    file.open(QIODevice::WriteOnly); 
    QDataStream out(&file); 

    out << d; 
    return 0; 
} 
+0

感谢。我将以相同的模式执行读操作符>>。 – 2012-02-26 15:06:05

+0

关于反序列化的任何建议,有n个派生类。我应该在所有派生类上使用Q_DECLARE_METATYPE并使用QMetaType类构造它们吗? – 2012-02-26 20:37:06

+0

是的,这听起来像是正确的方法(QVariant涉及某处)。 – Mat 2012-02-26 20:44:30