is it possible to simply serialize C++ objects

前端 未结 4 820
伪装坚强ぢ
伪装坚强ぢ 2020-12-22 05:03

Can you cast an object to a string of hex data (similar to how packets are sent) and then store that and then cast the object back? I know its possible with C structs which

4条回答
  •  臣服心动
    2020-12-22 05:27

    Can you cast an object to a string of hex data (similar to how packets are sent) and then store that and then cast the object back?

    No.
    (or perhaps I do not know how.)

    Note - tcp packets are not hex, or otherwise formatted, either.

    Casting the pointer to your data buffer does nothing to the data, nothing to the binary contents of an array of bytes. No conversion. No formatting.

    So the c-style cast to (unsigned char*) will NOT convert the contents to hex text.

    If you want to translate to/from hex format, you have to write code (i.e.operator>>() and operator<<()) to translate each byte into two characters. This is easy but processor expensive. (You can find many examples on the net.)


    is it possible to simply serialize C++ objects

    Yes.

    Many would emphasize the 'serialize' in your question, and worry about endian-ness, and other issues. 'Serialize' has specific meaning in certain contexts - persistent storage is where I first ran into these items.

    If, on the other hand, binary is ok, and you just want to send a binary packet to/from the file system, or over tcp/ip socket streams, all you need to do is use write/read to store/retrieve the object's data into/out of a (binary) file, or send/receive over stream socket.

    Consider the following:

     class Something
     {
     public:
        Something(void)   { clear(); }
        ~Something (void) { clear(); }
    
        void clear(void){for (int i=0; i<100; i+=1) m_data[i] = 0;}
    
        void init(void) {for (int i=0; i<100; i+=1) m_data[i] = char(i); }
    
        const char* data_GetAddr() { return m_data; }
        char*       data_PutAddr() { return m_data; }
    
        // show 3 bytes:
        void show(void) { std::cout << "m_data: "
                                    << m_data[0] << "  "
                                    << m_data[1] << "  "
                                    << m_data[2] << "\n"
                                    << std::endl;  }   
     private:
        char  m_data[100];
        // and various other POD here
     };
    
    
    
     int main (int, char**)
     {
        auto obj1 = new Something();
        obj1->init();
        obj1->show(); // show initialized data
    
        // cast does not convert from binary to text
        // so the following does not help
        // auto obj1Hex = (unsigned char*)obj1; 
    
        // but we can store obj1 to a file in binary
        std::stringstream ss;                        // a ram-base 'file'
    
        // store data to file using write.
        ss.write(obj1->data_GetAddr(), sizeof(Something));
    
        // now we allocate a receive buffer just as you have suggested
        auto obj2 = new Something();  // allocate space for another instance
        obj2->show();  // show this has 0's
    
        // retrieve obj data from file, installing it into obj2 working buffer.
        ss.read(obj2->data_PutAddr(), sizeof(Something));
    
        obj2->show();       // show results
    
        return(0);
     }
    

    The output looks similar to the following (emacs presents the binary 0, 1, 2 as the keystrokes needed to achieve them, i.e. control-@, control-A, control-B

    m_data: ^@ ^A ^B <<< obj1 after init()

    m_data: ^@ ^@ ^@ <<< uninitialized obj2 (all 0's)

    m_data: ^@ ^A ^B <<< obj2 after read, no init()

提交回复
热议问题