使用重新解释强制转换将结构或类保存到文件 [英] Using reinterpret cast to save a struct or class to file

查看:57
本文介绍了使用重新解释强制转换将结构或类保存到文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是教授在他的剧本中向我们展示的东西.我没有在编写的任何代码中使用此方法.

This is something the professor showed us in his scripts. I have not used this method in any code I have written.

基本上,我们采用一个类或结构,然后重新解释它并保存整个结构,如下所示:

Basically, we take a class, or struct, and reinterpret_cast it and save off the entire struct like so:

struct Account
{
    Account()
    {   }
    Account(std::string one, std::string two)
        : login_(one), pass_(two)
    {   }

private:
    std::string login_;
    std::string pass_;
};

int main()
{
    Account *acc = new Account("Christian", "abc123");

    std::ofstream out("File.txt", std::ios::binary);
    out.write(reinterpret_cast<char*>(acc), sizeof(Account));
    out.close();

这将产生输出(在文件中)

This produces the output (in the file)

ÍÍÍÍChristian ÍÍÍÍÍÍ              ÍÍÍÍabc123 ÍÍÍÍÍÍÍÍÍ     

我很困惑.这种方法真的有效吗,还是会导致UB,因为神奇的事情发生在各个编译器的异想天开的类和结构中?

I'm confused. Does this method actually work, or does it cause UB because magical things happen within classes and structs that are at the whims of individual compilers?

推荐答案

它实际上不起作用,但也不会引起未定义的行为.

It doesn't actually work, but it also does not cause undefined behavior.

在C ++中,将任何对象重新解释为char的数组是合法的,因此这里没有未定义的行为.

In C++ it is legal to reinterpret any object as an array of char, so there is no undefined behavior here.

但是,结果通常仅在类为POD(有效,如果该类是简单的C样式结构)且自包含(即,该结构没有指针数据成员)时才可用.

The results, however, are usually only usable if the class is POD (effectively, if the class is a simple C-style struct) and self-contained (that is, the struct doesn't have pointer data members).

此处,Account不是POD,因为它具有std::string个成员. std::string的内部是实现定义的,但不是POD,它通常具有指向存储实际字符串的堆分配块的指针(在您的特定示例中,实现使用小字符串优化)字符串的值存储在std::string对象本身中的位置).

Here, Account is not POD because it has std::string members. The internals of std::string are implementation-defined, but it is not POD and it usually has pointers that refer to some heap-allocated block where the actual string is stored (in your specific example, the implementation is using a small-string optimization where the value of the string is stored in the std::string object itself).

有几个问题:

  • 您并非总是会得到预期的结果.如果字符串较长,则std::string将使用在堆上分配的缓冲区来存储字符串,因此最终只能序列化指针,而不是指向字符串.

  • You aren't always going to get the results you expect. If you had a longer string, the std::string would use a buffer allocated on the heap to store the string and so you will end up just serializing the pointer, not the pointed-to string.

您实际上无法在这里使用序列化的数据.您不能只是将数据重新解释为Account并期望它能正常工作,因为std::string构造函数将不会被调用.

You can't actually use the data you've serialized here. You can't just reinterpret the data as an Account and expect it to work, because the std::string constructors would not get called.

简而言之,您不能使用这种方法来序列化复杂的数据结构.

In short, you cannot use this approach for serializing complex data structures.

这篇关于使用重新解释强制转换将结构或类保存到文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆