C ++将对象写入二进制文件

时间:2013-11-01 08:26:00

标签: c++ binaryfiles

问题:

  

错误:“&”运算符只能应用于变量或其他l值。

我尝试了什么:

  • dynamic_cast<char*>(e)
  • reinterpret_cast<char*>(e)
  • static_cast<char*>(e)
  • (char*) e

我正在尝试做什么:

  • 将数组e.data(private)写入二进制文件。

备注:

  • e.getSize()返回数组
  • 中的元素数
  • e []返回Employee对象。

代码:

fstream fout;
fout.open(filename.c_str(), ios::out|ios::binary);
if(fout.good())
{
    for(int i=0;i<e.getSize();i++)
    {
        fout.write((char*)&e[i], sizeof(e[i]));
    }
}
fout.close();

Employee.h

class Employee {
    friend std::ostream& operator<<(std::ostream&, const Employee &);
    private:
        int id;
        char name[50];
        char address[100];
        char phone[20];
        char department[100];
        int salary;
    public:
        Employee();
        ~Employee();
        Employee(int,char[],char[],char[],char[],int);
        bool operator==(Employee&);
};

我很遗憾该做什么,从我记得的fout.write((char*)&e[i], sizeof(e[i]));是如何写入二进制文件。

修改 e声明如下:    MYLIB::Bucket<Employee> e;

template <class T>
class Bucket {
    private:
        T* bkt;
        int size;
        int capacity;
        static const int stepsize = 10;

    public:
        Bucket();
        ~Bucket();

        void push_back(const T&);
        T operator[](int);
        int getSize();
        int getCapacity();
};

编辑2: fout.write(reinterpret_cast<char*>(e[i]), sizeof(e[i]));给我第122行:错误:使用reinterpret_cast进行转换? to char *不允许。 (第122行是刚引用的行)

编辑3:

tempemp = e[i];
fout.write((char*)(&tempemp), sizeof(e[i]));

编译但会出现分段错误,我会调查原因。 编译时,分段错误看起来无关。

2 个答案:

答案 0 :(得分:3)

 MYLIB::Bucket<Employee> e;

这似乎是一个容器。 e[i]按值为Employee。您需要使用&e[i]来获取此对象的地址,但您可以这样做,因为它是一个r值,因此您需要将其复制到非r值:

Employee copye = e[i];
fout.write((char*)&copye, sizeof(e[i]));

应该工作。

另一方面,这看起来像是可怕的代码,我不羡慕谁需要维护或阅读它。几点:

  • 您不应该使用内存中对象的二进制格式作为序列化格式。使用正确的序列化格式,如protobuf或xml或json
  • 为什么在使用std::vector std::list时拉出自己的奇怪容器?重新发明轮子总是不好的
  • 从容器中按值返回元素会创建降低性能的副本。

答案 1 :(得分:2)

我认为

T operator[](int);

返回一个临时对象,必须绑定到某个地址才能获取地址

const Employee& emp = e[i];
fout.write((char*)&emp, sizeof(emp));

可能有效,假设this answer是正确的,采用引用会延长临时对象的生命周期

另一种方法可能是返回对象的引用,这将删除临时对象的创建

const T& operator[](int);