您可以将对象强制转换为十六进制数据字符串(类似于数据包的发送方式)然后将其存储然后再将对象转换回来吗?我知道C语言结构可能是C ++中的基本对象。
不同系统的序列化兼容性并不重要。
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
答案 0 :(得分:4)
没有。原因:
a)动态分配的内存,即。 struct / class中的指针
b)结构的Endianess,int-size,padding等,成员的顺序......
其他事项:
“如果”有可能,则没有理由创建一个完整的对象
在覆盖它之前使用构造函数调用
在我看来,你过度使用汽车。
答案 1 :(得分:4)
这并不容易(并且通常不会自动执行),但像s11n这样的库可能会有所帮助。
我会考虑一些文字serialization格式,如JSON,例如jsoncpp或Yaml。当然,你需要编写一些代码。
如pasztorpisti所述,您可以考虑从C ++声明中获取一些代码。也许MELT可能对您有所帮助(您可以使用它自定义g++
以“提供有关程序类型的反映信息”,根据pasztopisti的说法)。但这需要数周的工作。
在开始设计应用程序时,可以尽早思考IMHO持久性和序列化。之后可能很难添加。
答案 2 :(得分:0)
可以将对象转换为十六进制数据字符串(类似于数据包的方式) 发送)然后存储然后再将对象投射回去?
没有。
(或许我不知道怎么做。)
注意 - tcp数据包不是十六进制或其他格式化。
将指针强制转换为数据缓冲区对数据没有任何作用,对字节数组的二进制内容没有任何作用。没有转换。没有格式化。
因此,c样式转换为(unsigned char *)将 NOT 将内容转换为十六进制文本。
如果要转换为十六进制格式,则必须编写代码(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&lt;&lt;&lt; init()
之后的obj1m_data:^ @ ^ @ ^ @&lt;&lt;&lt;未初始化的obj2(全0)
m_data:^ @ ^ A ^ B&lt;&lt;&lt;读取后的obj2,没有init()
答案 3 :(得分:0)
如果您只是想将C ++中的对象序列化为二进制blob数据,JSON或XML,您可以查看序列化库,例如cereal或{{3 }}
如果您需要支持原始指针或引用,Boost是可行的方法。如果你不需要序列化指向事物的原始指针,而是使用C ++ 11风格的智能指针或根本没有指针,我建议使用谷歌,因为它支持标准库中的几乎所有东西,而Boost有一个更有限的子集。