是否有可能系列化C ++对象 [英] is it possible to simply serialize C++ objects

查看:90
本文介绍了是否有可能系列化C ++对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可以对象转换十六进制数据的字符串(类似于数据包发送方式),然后存储,然后把对象回来?我知道,它与C结构可能这是基本对象undearneath在C ++中。

在不同系统的系列化兼容性并不重要。

 汽车的obj =新的东西();汽车objHex =(无符号字符*)目标文件;//商店objHex像一个分贝
//检索objHex汽车OBJ2 =新的东西(); //分配
* OBJ2 =(有什么*)objHex; //设置取消引用


解决方案

  

您可以对象转换十六进制数据的字符串(类似于如何包
  发送),然后存储,然后把对象回来了?


没有。结果
(也许是我不知道怎么办。)

请注意 - TCP报文均不是十六进制或其他格式,无论是

铸造指针,数据缓冲区无助于数据,没什么字节数组的二进制内容。任何转换。没有格式化。

因此​​,C样式转换到(无符号字符*)会的的转换的内容为十六进制的文本。

如果你想翻译到/从十六进制格式,你必须写code(i.e.operator >>()和operator<<())将每个字节转换成两个字符。这很容易,但处理器价格昂贵。 (您可以在网络上找到许多例子。)



  

是有可能系列化C ++对象


很多人会强调连载你的问题,并担心字节序等问题。 序列化在某些情况下特定的含义 - 持久性存储是我第一次遇到了这些项目。

如果,在另一方面,二是确定了,你只是想一个二进制包从文件系统发送到/,或通过TCP / IP套接字流,所有你需要做的就是使用写入/读取存储/检索对象的数据导入/出(二进制)的文件,或者发送/接收过流套接字。

考虑以下几点:

 类的东西
 {
 上市:
    东西(无效){清晰(); }
    〜事(无效){清晰(); }    void清除(无效){的for(int i = 0; I< 100; I + = 1)M_DATA [I] = 0;}    无效的init(空隙){对于(INT I = 0; I&小于100; I + = 1)M_DATA [I] =炭(ⅰ); }    为const char * data_GetAddr(){返回M_DATA; }
    字符* data_PutAddr(){返回M_DATA; }    //显示3个字节:
    无效显示(无效){性病::法院LT&;< M_DATA:
                                << M_DATA [0]&下;&下;
                                << M_DATA [1];&下;
                                << M_DATA [2]&下;&下; \\ n
                                <<的std :: ENDL; }
 私人的:
    烧焦M_DATA [100];
    //和各种其它这里POD
 }; INT主(INT,CHAR **)
 {
    汽车OBJ1 =新的东西();
    obj1->的init();
    obj1->显示(); //显示初始化数据    //投不从二进制转换为文本
    //所以下面没有帮助
    //自动obj1Hex =(无符号字符*)OBJ1;    //但我们可以OBJ1存储二进制文件
    的std :: stringstream的SS; //一个冲压基地'文件'    //存储数据到文件使用write。
    ss.write(obj1-> data_GetAddr()的sizeof(东西));    //现在我们分配就像你建议接收缓冲器
    汽车OBJ2 =新的东西(); //为另一个实例分配空间
    obj2->显示(); //显示这有0    //从文件中检索数据OBJ,将其安装到OBJ2工作缓冲区。
    ss.read(obj2-> data_PutAddr()的sizeof(东西));    obj2->显示(); // 显示结果    返回(0);
 }

输出类似于以下(emacs的presents二进制0,1,2作为按键需要实现它们,即控制 - @,控制A,控制-B

M_DATA:^ @ ^ A ^ B<<< OBJ1初始化后,()

M_DATA:^ @ ^ @ ^ @<<<未初始化OBJ2(全0)

M_DATA:^ @ ^ A ^ B<<< OBJ2读取后,没有的init()

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 are basically objects undearneath in C++.

Compatibility of the serialization across different systems isn't important.

auto obj = new Something();

auto objHex = (unsigned char*) obj;

// store objHex in like a db
// retrieve objHex

auto obj2 = new Something();  // allocate
*obj2 = (Something*) objHex;  // set the dereference

解决方案

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()

这篇关于是否有可能系列化C ++对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆