将结构和类写入磁盘

时间:2010-05-22 18:08:13

标签: c++ class file-io struct g++

以下函数将结构写入文件。

#define PAGESIZE  sizeof(BTPAGE)
#define HEADERSIZE 2L

    int btwrite(short rrn, BTPAGE *page_ptr)
    {
        long addr;
        addr = (long) rrn * (long) PAGESIZE + HEADERSIZE;
        lseek(btfd, addr, 0);
        return (write(btfd, page_ptr, PAGESIZE));
    }

以下是结构。

typedef struct {
    short keycount;             /* number of keys in page   */
    int  key[MAXKEYS];              /* the actual keys      */
    int  value[MAXKEYS];            /* the actual values        */
    short child[MAXKEYS+1];     /* ptrs to rrns of descendants  */
} BTPAGE;

如果我将结构更改为类会发生什么,它仍然会起作用吗?

如果我添加了类函数,它在磁盘上占用的大小会增加吗?

4 个答案:

答案 0 :(得分:4)

你需要在这里学到很多东西。

  • 首先,您将结构视为字节数组。由于strict aliasing rule,这是严格未定义的行为。任何事情都可能发生。所以不要这样做。使用正确的序列化(例如通过boost)代替。是的,这很乏味。是的,这是必要的。
  • 即使你忽略了undefined,并选择依赖某些特定的编译器实现(即使在下一个编译器版本中也可能会改变),仍然有理由不这样做。
    • 如果您将文件保存在一台计算机上,然后将其加载到另一台计算机上,则可能会出现垃圾,因为第二台计算机使用不同的浮动表示形式,或者使用不同的endianness,或者具有不同的alignment rules等等。
    • 如果您的结构包含任何指针,则很可能逐字保存它们然后将它们加载回来将导致地址不会指向任何有意义的地方。
  • 通常,当您添加成员函数时,会发生以下情况:
    • 函数的机器代码存储在所有类实例共享的位置(复制它没有意义,因为它在逻辑上是不可变的)
    • 隐藏的“this”指针在被调用时传递给函数,因此它知道调用了哪个对象。
    • 这些都不需要实例中的任何存储空间。
  • 但是,当您添加至少一个虚拟函数时,编译器通常还需要添加一个名为vtable的数据块(在其上读取)。这使得可以根据对象的当前运行时类型(也称为多态)调用不同的代码。因此,您添加到类中的第一个虚拟函数 会增加对象大小。

答案 1 :(得分:3)

在C ++中,structclass之间的区别仅仅在于默认情况下结构的成员和基类是公共的,而对于类,它们默认是私有的。

简单地将结构的字节写入文件然后再次读回它的技术仅在结构为plain old data, or POD, type时才有效。如果你修改你的结构使它不再是POD,那么这种技术就不能保证工作(描述是什么使得POD结构列在这个链接问题的答案中的规则)。

答案 2 :(得分:1)

如果班级有任何虚拟功能,那么你就麻烦了;如果没有虚函数,你应该还可以(当然,同样适用于结构,因为它也可以有虚函数:结构和类之间的区别只是结构中的默认可见性是公共的,在类中它是私人的。)

答案 3 :(得分:0)

如果您正在进行更多类的序列化,请考虑使用谷歌协议缓冲区或类似的see this question