使用重新解释强制转换将结构或类保存到文件 [英] Using reinterpret cast to save a struct or class to file
问题描述
这是教授在他的剧本中向我们展示的东西.我没有在编写的任何代码中使用此方法.
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屋!