Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

What is pickling in C++ Qt if you're used to PyQt5?



  • I'm porting an application from Python to C++ because of scene rendering speed of graph-theory type content. When you add two functor arrows between two categories and put just one morphism in the first category. The whole system together has a latency when updating when you're moving a single object node inside the first category. This is due to the amount of time per arrow adjustment and the fact that child items are always contained in the painted (and live updated) bounds of the parent nodes. Anyway, I just wanted to explain why I'm doing this.

    DataStream& operator <<(DataStream& out, const TabWidget& t)
    {
        out << static_cast<qint32>(t.count());
        out << reinterpret_cast<std::uintptr_t>(&t);
        return out;
    }
    
    DataStream& operator >>(DataStream& in, TabWidget& t)
    {
        int count;
        in >> count;
        std::nullptr_t ptr;
        in >> ptr;
        in[ptr] = &t;
        return in;
    }
    

    So the subclassed DataStream has a memo of objects, and that's how you can pickle pointers to objects throughout the app's code. Is this the canonical way of doing things on the C++ side?


  • Lifetime Qt Champion

    Hi,

    You don't necessarily pickle in C++.

    Data transfer depends on your architecture. Without known more about it it's difficult to come up with a strategy.



  • Pickling is serializing an object. Are you intending to reproduce an object by serializing its pointer? If so, then you are not going to get what you expect. A pointer points to a memory location and is only useful on the system it was created.

    If that is not what you intended why serialize a pointer at all? I read your description, but its domain of terminology is very specific and I don't have a frame of reference.



  • @fcarney Clearly what I mean is object memoization via the pointer values, thus keeping track of them in a memo (a map) .

    If you save the map also to file, then upon loading you had also stored the pointer (and pointed-to-object) whereever it occured, so you then just call corresponding setObjectPointer(), wherever it occured. Seems pretty complicated, so I'm wondering if there is a better algorithm.



  • @SGaist What do you mean by my architecture? Of code? I need a general purpose serialization go-to as well as one that can handle cyclicity of objects (via pointers / references) the obvious solution is to memoize sort of how deepcopying works in Python (uses a memo param) and most likely how pickling works as well, internally.


  • Lifetime Qt Champion

    @enjoysmath It doesn't make sense to store pointers in a file and restore them later as they will be invalid. In C++ you have to allocate the memory the pointer is pointing to:

    int* p = new int;
    

    For maps there is QMap in Qt.
    If you want to store objects into a file take a look at https://doc.qt.io/qt-5/qdatastream.html



  • Pickling in Python depends upon introspection. Python has the ability to introspect an object solely by its reference/pointer. C++ does not have that ability to introspect. Objects have to have methods to serialize the data. Example:

    #include <QCoreApplication>
    #include <QDebug>
    #include <QDataStream>
    #include <QByteArray>
    
    struct complex_object{
        QString m_string;
        float m_float;
        int m_int;
    };
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        complex_object cp;
        cp.m_string = "Some 💩";
        cp.m_float = 0.666;
        cp.m_int = 42;
    
        qInfo() << "before save:" << cp.m_string << cp.m_float << cp.m_int;
    
        QByteArray data; // used by socket stuff to hold data
        QDataStream sdata(&data, QIODevice::WriteOnly);
        sdata << cp.m_string << cp.m_float << cp.m_int;  // this serializes the data
    
        qInfo() << "store/retrieve data from file or other storage";
    
        complex_object cp2;
        QDataStream rdata(&data, QIODevice::ReadOnly);
        rdata >> cp2.m_string >> cp2.m_float >> cp2.m_int;  // this deserializes the data
    
        qInfo() << "after restore:" << cp2.m_string << cp2.m_float << cp2.m_int;
    
        return a.exec();
    }
    

    so in your memoization function:

    Object getObject(int indentifier){
        //if exists deserialize into object
        // else create object
        return object;
    }
    

Log in to reply