reinterpret_cast做二进制的是什么?

时间:2016-06-10 15:00:08

标签: c++ struct casting

我正在用C ++编写一个记录器,我来到了我想要记录日志并写入文件的部分。

我创建了一个LogRecord结构,并希望将其序列化并以二进制模式将其写入文件。

我已经阅读了一些关于C ++序列化的帖子,其中一个答案包括以下代码片段:

reinterpret_cast<char*>(&logRec)

我试过阅读有关reinterpret_cast及其作用的内容,但我无法完全理解后台发生的事情。

根据我的理解,它需要一个指向我的struct的指针,并将其转换为指向char的指针,因此它认为保存我的struct的内存块实际上是一个字符串,是真的吗?这怎么办?

4 个答案:

答案 0 :(得分:9)

内存地址只是一个内存地址。内存本身并不特殊 - 它只是一个庞大的字节数组,对于我们所关心的所有内容。赋予记忆意义的是我们用它做的事情,以及我们通过它观察它的镜头。

指向struct的指针只是一个整数,它指定了一些内存的偏移量 - 当然,你可以以任何你想要的方式处理一个整数,作为指向某个任意字节数的指针(char或多个)。

除了允许您将内存地址的一个视图转换为内存地址的另一个视图外,

reinterpret_cast()没有做任何特殊操作。您仍然可以正确处理该内存地址。

例如,char*是在C ++中引用字符串的传统方式 - 但类型char*字面意思是“指向单个字符的指针”。它是如何表示指向以null结尾的字符串的指针?按惯例,就是这样。我们根据具体情况对这种类型进行不同的处理,但我们应该确保这样做是正确的。

例如,您如何知道通过指向结构的char*指针读取多少字节?类型本身为您提供零信息 - 由您自己知道您确实有一个指向固定长度结构的面向字节的指针。

请记住,在引擎盖下,机器没有类型。如果你在每一行写一篇文章,或者如果你乱涂乱画,那么一张纸并不在乎。这就是我们对待它的方式 - 以及我们使用的工具(C ++)如何对待它。

答案 1 :(得分:3)

二进制,它什么都不做。这种铸造是一种更高级别的概念,与任何实际的机器指令无关。

在低级别,指针只是一个包含内存地址的数值。告诉编译器没什么可做的,虽然您认为目标内存包含struct,但现在请认为它包含char&#34;。实际地址本身并没有任何改变。

答案 2 :(得分:1)

  

根据我的理解,它需要一个指向我的struct的指针,并将其转换为指向char的指针,因此它认为保存我的struct的内存块实际上是一个字符串,是真的吗?

  

这怎么办?

一个字符串只是一个字节序列,你的对象只是一个字节序列,所以它是如何工作的。

但如果您的对象逻辑不仅仅是一个字节序列,它赢了。任何间接,你都被冲洗了。此外,任何实现定义的填充或表示/字节顺序和您的数据都是不可移植的。这可能是可以接受的;这实际上取决于你的要求。

答案 3 :(得分:0)

将结构体转换为字节数组(字符串)是二进制序列化的经典低影响方法。这是基于结构内容在内存中连续存在的假设。转换允许我们使用普通API将此数据写入文件或套接字。

仅当数据是连续的时才有效。对于C ++术语中的C样式结构或POD,这是正确的。它不适用于复杂的C ++对象或任何带有指向结构外部存储的指针的结构。对于文本数据,您需要使用固定大小的字符数组。

struct {
    int num;
    char name[50];
};

将正确序列化。

struct {
    int num;
    char* name;
};

将无法正确序列化,因为字符串的数据存储在struct之外;

如果要通过nework发送数据,还需要确保结构已打包或至少已知对齐,并且整数转换为一致的字节顺序(网络字节顺序通常为大端)

相关问题