将复杂对象写入文件 [英] writing a complex object into file

查看:51
本文介绍了将复杂对象写入文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class student{
private:
    char name[50];
    int ID;
public:
    student(char* n, int id){
        strcpy(name, n);
        ID=id;
    }
};

class school{
private:
    char name[50];
    student* students[10];
public:
    school(char* n){
        strcpy(name,n);
        for(int i=0; i<10; i++){
            students[i]=NULL;
        }
    }

    void addStu(char* n, int id){
        students[0]=new student(n,id);
        students[1]=new student(n,id);
        students[2]=new student(n,id);
        students[3]=new student(n,id);
        students[4]=new student(n,id);
        students[5]=new student(n,id);
        students[6]=new student(n,id);
        students[7]=new student(n,id);
        students[8]=new student(n,id);
        students[9]=new student(n,id);
    }
};

int main(){
    school* s = new school("Kiss");
    s->addStu("Jason", 1000);
    ofstream sch;
    sch.open("school.dat" ios::out|ios::app|ios::binary);
    sch.write((char*)s, sizeof(school));
    sch.close();

}



学校"类具有学生"类作为其属性.

并且我想将学校对象"s"写入文件.

然后,我想读取文件并将学校对象重新加载到内存中.

我想问的是..
1.即使我以sizeof(school)编写代码,代码也能按预期工作吗?
2.当我读回文件时,可以从文件中获取正确的数据吗?

那是我的问题..我希望有人能帮助我~~

谢谢

干杯,



''school'' class has ''student'' class as its attribute.

and I would like to write the school object ''s'' to a file.

Then I wanna read the file and load the school object back on the memory.

What I would like to ask is..
1. does the code works as intended, even if I wrote it as sizeof(school)?
2. would I get proper data from the file when I read it back?

that is my question.. I hope someone please help me~~

Thank you,

cheers,

推荐答案

也可以看看boost::serialization [

通过写入二进制内容将C ++对象写入文件相当脆弱.这将取决于您使用的编译器和编译器选项.在某些平台上,整数以大端格式存储,而在其他小端格式下使用.

如果您决定采用这种结构,则结构应为POD(普通旧数据)类型,否则,可能会有诸如虚拟表之类的附加内容从文件中读取时会被弄乱.

对齐将在数据中产生孔.上面的结构"在32位平台上通常为56字节,其中通常使用4字节对齐.如果该程序是用64位编译的,则可能是64个字节...可以使用编译器选项和编译指示来控制对齐方式,但不能移植.

通常,您最好尝试为此目的找到一个库,因为专家会解决这些问题....实际上,在大多数情况下,应考虑将XML格式用于配置数据,将数据库用于大型数据表.

如果您的目标是MFC或C ++/CLI(可能还有其他一些目标),则您可能已经拥有了所需的东西.例如,在.NET中,内置了对XML的支持.

如果要编写自己的代码,则应编写自己的函数来读写数据.然后,您应该有一个用于读取和写入数据的实用程序类.

This is rather fragile to write C++ object to file by writing their binary content. It will depend on which compiler and which compiler options you are using. On some plateform, interger are stored in big-endian format while on other little endian format is used.

A structure should be a POD (Plain old data) type if you decide to go this way as otherwise there could be additionnal content like virtual tables that could be messed up when reading back from a file.

The alignment will create holes in data. The above "structure" will typically be 56 bytes on a 32 bit plateform where 4 bytes alignment is generally used. If that programm is compiled in 64 bit, it might be 64 bytes... There are compiler options and pragma to control the alignement but there are not portable.

Typically, it would be best for you to try to find a library for that purpose as experts would have deal with those problems... In fact, XML format should be considered for configuration data and a database for tables of large data in most situations.

If your target is MFC or C++/CLI (and probably some other target), you might already have what you need. For example, in .NET, there is built-in support for XML.

If you want to write your own code, then you should write your own functions to read and write data. You should then have a utility class for reading and writing data.

class stream_helper
{
public:
    stream_helper(stream &the_stream_) : the_stream(the_stream_) { }

    int read_int() { /* code here */ }
    int read_string() { /* code here */ }


    void write_int(int value) { /* code here */ }
    void write_string(char const *text) { /* code here */ }

private:
    stream &the_stream;
};



您还可以重载运算符<<和>>为了更方便使用.

如果不使用现有的库,将很难正确地处理类似指针(对象图)的思维.此外,通常应添加一些跟踪以进行验证和版本控制.



You could also overload operators << and >> to make it more convenient to uses.

Without using an existing librairy, it will be hard to handle think like pointers (graph of objects) correctly. Also, typically some tracking should be added for validation and versionning.


从某种意义上说,它可以工作,但不会获得预期的结果.问题出在您的student上,因为它们都是指针,所以当您编写school对象时,您正在编写的是指向学生的指针,而不是指向其内容的指针.在序列化/反序列化对象时,应始终使对象保存其自身的内容,通过迭代每个元素或子对象并让它们保存自身来保存原样"元素类型和对象类型.因此,对于您的学校目标,您可以执行以下操作:
In a way, yes it would work, but you would not get the results you expect. The problem comes with your students, as they are all pointers, so when you write the school object, you are writing pointers to the students but not their content. When serialising/deserialising objects you should always get the object to save its own content, saving elemental types ''as is'' and object types by iterating over each element or sub-object and getting them to save themselves. So for your school object you would do something like:
school.save();

// the save code is:
    write (name); // the character string, perhaps preceded by a length item.
    write (count); // the number of students in school
    foreach (student in school)
        student.save();

        // student.save code is
        {
            write (name); // see comment above
            write (ID);
        }

write (EOFmark); // signify no more data


要回读,您只需扭转此过程,即可根据需要创建新对象.


To read back you would just reverse this process, creating new objects as required.


这篇关于将复杂对象写入文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆