C++ 对类使用fwrite()时会发生什么?

C++ 对类使用fwrite()时会发生什么?,c++,class,C++,Class,假设我有以下几点: class dataClass { public: int someData; float moreData; void setData(); }; dataClass data; 如果调用fwrite&data,sizeofdata,1,outputFilePointer;,会发生什么;?代码是否会表现为dataClass没有函数,或者我必须为每个成员调用fwrite?只要您的类是类型,您的类是类型,代码就可以正常工作。只要您的类是类型,您的类是类型

假设我有以下几点:
class dataClass {
public:
    int someData;
    float moreData;
    void setData();
};
dataClass data;

如果调用fwrite&data,sizeofdata,1,outputFilePointer;,会发生什么;?代码是否会表现为dataClass没有函数,或者我必须为每个成员调用fwrite?

只要您的类是类型,您的类是类型,代码就可以正常工作。

只要您的类是类型,您的类是类型,代码就可以正常工作。

除非您动态分配了成员,一个简单的memcpy,实际上就是这个结构,它会工作好的警告:只在同一个平台上,即endian和32/64,除非你有动态分配的成员,一个简单的memcpy,实际上就是这个结构,它会工作好的警告:只在同一个平台上,例如endian和32/64,因为这是一个POD类,所以可以将其视为一个字节桶。

因为这是一个POD类,所以可以将其视为一个字节桶。

在这种情况下,您的类是POD,所以它的工作方式与普通的旧C结构完全相同,也就是说,它将转储磁盘上数据的内存表示,包括编译器可能插入的填充字节

<>但是,如果虚拟方法、虚拟继承和其他C++的东西被踢进去,你可能会看到奇怪的东西,你不仅会看到正常的数据字段,还会看到VTHT指针,或者其他编译器自动输入的东西;我认为多重继承也会增加混乱


但是请注意,在任何情况下,仅对对象调用fwrite都应该是无害的,尽管这可能是未指定的行为,但我没有检查;相反,如果您尝试从文件中反序列化一个非POD对象,而只使用一个fread,则可能会出现问题。例如,正确的vtable指针可能会被存储在文件中的指针覆盖,该指针可能不再有效,这将使所有内容在下一次虚拟调用时崩溃。

在这种情况下,您的类是POD,因此,它的工作原理与普通的旧C结构完全相同,也就是说,它将转储磁盘上数据的内存表示,包括编译器可能插入的填充字节

<>但是,如果虚拟方法、虚拟继承和其他C++的东西被踢进去,你可能会看到奇怪的东西,你不仅会看到正常的数据字段,还会看到VTHT指针,或者其他编译器自动输入的东西;我认为多重继承也会增加混乱


但是请注意,在任何情况下,仅对对象调用fwrite都应该是无害的,尽管这可能是未指定的行为,但我没有检查;相反,如果您只想用FROAD从文件中反序列化一个非POD对象,则可能会出现问题,例如,正确的VTABLE指针可能被文件中存储的一个改写,这将不再有效,这会使所有的东西在下一个虚拟调用中被炸毁。C++中的

< P>每个对象都由字节序列表示,任何类型的对象都可以重新解释为字节数组。这正是调用fwrite时发生的情况:给它一个指向对象的指针,告诉它对象有多大(以字节为单位),然后它将对象重新解释为一个包含那么多字节的数组

类型是否为POD并不重要;非POD类型的对象也可以重新解释为字节数组。将非POD类型的对象重新解释为字节数组没有什么未定义的。结果主要是为非POD类型定义的实现,但这完全是另一回事

非POD类型的对象的问题在于,一旦您使用fwrite将其底层存储的副本复制到文件中或内存中的其他位置,例如,您就无法对该副本执行很多操作。您不能将副本重新加载到内存中,并期望将其作为原始对象使用,也不能将字节的副本作为原始对象类型的对象重新解释

具有指针类型的数据成员的类也存在类似的问题,即使这些类是POD类:因为您只复制了指针的值,而没有复制指针所引用的对象,所以实际上还没有复制所需的所有数据。您无法有意义地从文件中读回复制的数据,因为最终将得到不引用实际对象的指针,这当然不是您的意图


正如其他人所说,即使您有一个自包含的POD类型的对象,您也无法将结构以可移植的方式写入这样的文件,并期望它们在其他平台上被正确读回,因为Funmental类型的大小和表示方式不同,和其他实现定义的东西,如数据结构填充和对齐。C++中的

< P>,每个对象都由一个字节序列表示,任何类型的对象都可以重新解释为字节数组。这正是 调用fwrite时会发生什么:给它一个指向对象的指针,告诉它对象有多大(以字节为单位),然后它将对象重新解释为一个包含那么多字节的数组

类型是否为POD并不重要;非POD类型的对象也可以重新解释为字节数组。将非POD类型的对象重新解释为字节数组没有什么未定义的。结果主要是为非POD类型定义的实现,但这完全是另一回事

非POD类型的对象的问题在于,一旦您使用fwrite将其底层存储的副本复制到文件中或内存中的其他位置,例如,您就无法对该副本执行很多操作。您不能将副本重新加载到内存中,并期望将其作为原始对象使用,也不能将字节的副本作为原始对象类型的对象重新解释

具有指针类型的数据成员的类也存在类似的问题,即使这些类是POD类:因为您只复制了指针的值,而没有复制指针所引用的对象,所以实际上还没有复制所需的所有数据。您无法有意义地从文件中读回复制的数据,因为最终将得到不引用实际对象的指针,这当然不是您的意图


正如其他人所说,即使您有一个自包含的POD类型的对象,您也无法将结构以可移植的方式写入这样的文件,并期望它们在其他平台上被正确读回,因为Funmental类型的大小和表示方式不同,以及其他实现定义的东西,如数据结构填充和对齐。

为什么不试试看:?b/c try and see不会告诉您标准是否允许某些内容,因此是可移植的?该方法是可移植的,但不应期望书面内容跨平台匹配。宇宙将自行内爆,所有存在都将结束。您为什么不试试看:?b/c try and see不会告诉您标准是否允许某些内容,因此是可移植的?该方法是可移植的,但编写的内容不应跨平台匹配。宇宙将自行内爆,所有存在都将结束。动态分配与类是POD还是C++0x标准布局无关。@Ben,我不确定是否收到您的评论,我说的是会员,不是班级本身,没关系。指针的记忆是完全合法的。另一方面,默认构造函数、虚拟函数、多重继承、混合访问说明符或子对象的非PODness都使用memcpy未定义的行为。@Ben:我想重点是在文件中写入指针值没有任何用途?@UncleBens:这当然有问题,但是,如果文件重新加载到同一个会话中就可以了。动态分配与类是POD还是C++0x标准布局无关。@Ben,我不确定是否收到您的评论,我说的是成员,而不是类本身。没关系。指针的记忆是完全合法的。另一方面,默认构造函数、虚拟函数、多重继承、混合访问说明符或子对象的非PODness都使用memcpy未定义的行为。@Ben:我想重点是在文件中写入指针值没有任何用途?@UncleBens:这当然有问题,但如果将文件重新加载到同一会话中,则可以。这可能是未指定的行为在几乎所有情况下,获取输出的数据都未指定。这可能是未指定的行为在几乎所有情况下,获取输出的数据都未指定。