【问题标题】:Is it possible to create a byte array from a class in the same way as a struct?是否可以以与结构相同的方式从类创建字节数组?
【发布时间】:2021-12-13 21:29:48
【问题描述】:

我知道您可以有效地执行以下代码来将结构体转换为字节数组,

struct Dummy
{
  int a;
  int b; 
};

Dummy data;
char* buffer = reinterpret_cast<char*>(&data);

然后我们可以使用 char 数组指针一个一个地访问这 8 个字节中的每一个。

我的问题是你能以类似的方式对班级做同样的事情吗?

class Dummy
{
private:
  int a;
  int b; 
};

Dummy data;
char* buffer = reinterpret_cast<char*>(&data);

【问题讨论】:

  • classstruct 仅在默认访问修饰符上有所不同。
  • 所以在幕后完全一样?即使订购?
  • 这是目前标准的灰色地带。 buffer 是一个有效的指针,但你能用它做什么取决于你对标准的解释。乐观的解释(我相信预期的解释)将允许这两种情况都访问整个表示。但是Dummy 在这两种情况下都可以轻松复制,对于非平凡类型,您可以访问的实际表示不会很有意义。您无法安全地对其进行写入,并且您无法利用从其中读取的信息来做很多事情。
  • @FrançoisAndrieux:abprivate 时,标准是否保证它们的排序?我希望该标准允许为 private 成员重新排序以进行优化,但我不确定。如果允许重新排序,则无法保证读取的字节甚至来自特定成员,即使大小和填充规则都是已知的。
  • 是的,任何类型的任何对象 - 您都可以检查字节。

标签: c++


【解决方案1】:

class 和 struct 之间的唯一区别是默认访问修饰符,structpublicclassprivate。在 c++ 标准中,您实际上可以阅读类,而在示例中您有结构:https://eel.is/c++draft/class.prop

从技术上讲,您的代码是正确的,例如它不会导致未定义的行为。不违反严格的别名规则 - 您可以使用 char 类型来访问对象的存储值:

http://www.eel.is/c++draft/expr.prop#basic.lval-11.3

问题是你想用这个指针做什么?例如,如果你想实现序列化,那么你需要确保你的类is_trivially_copyable

https://en.cppreference.com/w/cpp/types/is_trivially_copyable

不是潜在重叠子对象的普通可复制类型的对象是唯一可以使用 std::memcpy 安全复制或使用 std::ofstream::write()/std 序列化到二进制文件/从二进制文件序列化的 C++ 对象::ifstream::read()。

你的班级通过了这个测试:

static_assert(std::is_trivially_copyable<Dummy>::value, "Cannot be copied with memcpy");

您还需要了解此类对象访问可能导致的各种问题:对齐、字段填充、打包等。在 Visual Studio 下,我曾经使用#pragma pack(1) 来确保类中的所有字段都正确字节打包。但这会删除许多优化,除非没有其他解决方案,否则不应使用。

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 2017-12-28
    相关资源
    最近更新 更多