在C中,数据通常以struct
数据类型组织。保存在随机访问文件中非常方便,因为您可以在结构上使用sizeof
跳转到所需的记录。
我不清楚在C ++中执行此操作的最佳方法是什么,其中您有一个包含数据的类(以及一些当然不需要保留的成员函数)。直接存储类似乎是错误的,因为当然这将包括指向函数的指针以及那些曾经持久存档到文件中的东西。
我能想到的另一种方法是将类中的成员数据(需要持久化)更改为struct
,并更改访问者函数以查看内部数据结构。它似乎有点过于交织,但似乎是避免两次复制每个字段的唯一合理方式(一次在单独的struct
中,一次在类中)。
当你继承时,这当然会中断,派生类会添加新字段。虽然这不是C ++和随机访问文件特有的问题,但它面临许多其他对象持久性方法(包括其他编程语言中流行的ORM包)different possible strategies even when saving to a database table for instance。
是否有任何'事实上的标准'人们通常在C ++中使用的方法来保存文件中的类数据?无需在整个地方复制东西?
答案 0 :(得分:3)
简短回答:这取决于
中等答案:它取决于C struct中的相同,可以直接序列化。
答案很长:如果类A
只是普通旧数据,那么它将是可序列化的,就像使用C结构一样,即二进制副本和加载sizeof(A)
字节。如果一个类只包含原始类型成员或它们的数组,和/或它们本身就是POD的子对象,则该类是POD对象。它可以有方法或静态方法,但没有虚拟方法(甚至不是虚拟析构函数)。
例如char数组是可以接受的,但没有指针,没有字符串,没有引用,并且(通常来说)标准库中没有对象(特别是没有std :: string)。
当然,由于它直接存储和加载二进制数据表示,它最终不能在不同的体系结构中移植,但可以用于本地保存状态。
答案 1 :(得分:2)
在C ++中,struct
和class
之间的唯一区别是它们的默认可见性; struct
默认为public,而class
默认为private。您可以使用struct
完成使用class
所做的任何事情。两者都可以有构造函数,析构函数,成员函数,基类型,虚拟成员等。
只要一个类型可以轻易复制(即类型有一个简单的析构函数,复制构造函数,移动构造函数,复制分配运算符和移动赋值运算符),或者如果你使用的是C ++ 98,那么就是POD类型它可以像在C中一样序列化到文件中。请注意,任何具有虚拟成员的类型,或者从具有虚拟成员的类型继承(虚拟或其他)的类型都不是简单的可复制。
编辑:非虚拟成员函数不会影响类型的布局。没有指向这些函数的指针存储在对象本身中。
答案 2 :(得分:0)
如果所有成员函数都是无状态的(在成员函数中没有定义静态局部变量),则C ++类和C样式结构之间没有区别:您只序列化每个类实例的成员数据。
进一步澄清一下,当您编写序列化程序(或更常用的是序列化库)时,您永远不会存储vtable,因为没有意义:只有成员数据特定于对象实例,而vtable是定义的在课堂上。 因此,拥有虚函数的唯一真正影响是您不再处理POD对象:您不能简单地将整个结构内存转储到磁盘上,并且必须将一个字段序列化为另一个字段