【发布时间】:2022-01-23 17:38:25
【问题描述】:
环顾四周,我发现很多地方都解释了获取某个对象(类或结构)大小的方法。我读到了填充,关于虚函数表影响大小以及“纯方法”对象的大小为 1 个字节的事实。但是我找不到这些是关于实现的事实还是 C++ 标准的事实(至少我无法找到所有这些事实)。
特别是我处于以下情况:我正在处理一些在某些对象中编码的数据。这些对象不持有指向其他数据的指针。它们不从任何其他类继承,但它们有一些方法(非虚拟)。我必须将这些数据放在缓冲区中以通过某个套接字发送它们。现在阅读我上面提到的内容,我只是将我的对象复制到发送缓冲区,注意到数据已正确“序列化”,即对象的每个成员都被复制,方法不会影响字节结构。
我想知道我得到的只是因为编译器的实现还是标准规定的。
【问题讨论】:
-
在此处阅读有关序列化的更多信息; isocpp.org/wiki/faq/serialization。请注意,当您在“另一端”收到数据时,将其转换为对象指针不会产生对象实例(不调用 new),并且您将没有有效的对象。您需要创建一个可以使用数据创建有效实例的构造函数。 (你也可以看看 C++20 的 bitcast)
-
Objects and alignment 讨论了对齐和填充(稍微),并在底部有参考。根据您的数据是什么,对齐和填充可能在整个系统中保持不变,或者它们可能不同。使用指定位宽整数比使用实现定义的类型(如
int或long)更安全。不同的架构将表示具有不同字节序的多字节整数。等等。我正在研究的微控制器具有 32 位最大对齐,因此 64 位数字是 32 位对齐的。 -
在不知道如何将来自对象的数据编码到通过套接字发送的缓冲区的情况下,这是不可能的。这不仅仅是关于 vtables(标准不需要,顺便说一句,即使大多数现代编译器在具有虚函数的
class/struct类型中使用它们)或填充。这是关于您所做的任何假设,这些假设可能并非在所有编译器上都普遍适用(例如,int的大小、字节序、浮点格式等)。 -
您可以简单地发送描述对象的 JSON,然后另一端读取数据的语言无关紧要。由语言来确定 JSON 所陈述的内容,并从中创建相关对象。
标签: c++ object serialization