是否可以简单地序列化C ++对象

你可以将一个对象转换为一个hex数据字符串(类似于数据包的发送方式)然后存储它然后再将对象转换回来吗? 我知道它有可能使用C结构,它基本上是C ++中的undearneath对象。

不同系统之间序列化的兼容性并不重要。

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 

你可以将一个对象转换为一个hex数据字符串(类似于数据包的发送方式)然后存储它然后再将对象转换回来吗?

没有。
(或许我不知道怎么做。)

注 – tcp数据包不是hex或其他格式化。

将指针强制转换为数据缓冲区对数据没有任何作用,对字节数组的二进制内容没有任何作用。 没有转换。 没有格式化。

所以c样式转换为(unsigned char *) 不会将内容转换为hex文本。

如果要转换为hex格式,则必须编写代码(ieoperator >>()和operator <<())将每个字节转换为两个字符。 这很简单,但处理器价格昂贵。 (你可以在网上找到很多例子。)


是否可以简单地序列化C ++对象

是。

许多人会强调你的问题中的“序列化”,并担心字符串和其他问题。 ‘Serialize’在某些情况下具有特定含义 – 持久存储是我第一次遇到这些项目的地方。

另一方面,如果二进制文件没问题,并且您只想向文件系统发送二进制数据包,或者通过tcp / ip套接字流发送二进制数据包,那么您需要做的就是使用write / read来存储/检索对象的数据进出(二进制)文件,或通过流套接字发送/接收。

考虑以下:

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

输出类似于以下内容(emacs将二进制0,1,2表示为实现它们所需的击键,即control-@,control-A,control-B

m_data:^ @ ^ A ^ B <<< obj1在init()之后

m_data:^ @ ^ @ ^ @ <<< uninitialized obj2(全0)

m_data:^ @ ^ A ^ B <<< obj2读后,没有init()

不。理由:
a)动态分配的内存,即。 struct / class中的指针。
b)结构的Endianess,int-size,padding等,成员的顺序……

其他事情:
“如果”有可能,则没有理由创建一个完整的对象
在覆盖它之前使用构造函数调用。
在我看来,你过度使用汽车。

这并不容易(并且通常不会自动执行),但像s11n这样的库可能有所帮助。

我会考虑一些像JSON这样的文本序列化格式,例如jsoncpp或Yaml 。 当然,你需要编写一些代码。

正如pasztorpisti评论的那样,您可以考虑从C ++声明中获取一些代码。 也许MELT可能会帮助你(你可以用它自定义g++以“提供关于程序类型的reflection信息”,根据pasztopisti的话)。 但这需要数周的工作。

顺便说一句,难题是如何处理指针,特别是指向共享同一个尖头对象的指针,以及指向代码的指针。 也许对于您的特定应用程序,事情可能会更简单。 阅读有关垃圾收集和持久性的内容 ; 两者都有共同关心的问题。

在开始设计应用程序时,可以尽早思考IMHO持久性和序列化。 之后可能很难添加。

如果您只想将C ++中的对象序列化为二进制blob数据,JSON或XML,您可以查看序列化库,如Grain或Boost序列化 。

如果您需要支持原始指针或引用,Boost是可行的方法。 如果您不需要将原始指针序列化,而是使用C ++ 11样式的智能指针或根本没有指针,我建议使用Grain,因为它支持标准库中的所有内容,而Boost有一个更有限的子集。