Запись / чтение необработанных объектов в файл - PullRequest
1 голос
/ 31 марта 2012

Проблема: мне нужно писать / читать объекты из файла. Это потому, что мне нужно записать / прочитать std :: list в файл, но в любом случае. Не только с T = int (это было бы просто),но с любым параметром.В Java с OutputFileStream и InputFileStream это было возможно, но я полагаю, что это просто функция JVM.Однако я пытаюсь читать / записывать объекты в файл:

template <class T>
bool write_object(std::fstream& out, const T& object)
{
    bool result=false;
    char* ptr;
    const unsigned long size=sizeof(object);
    if(out.good())
    {
        result=true;
        ptr=(char*)&object;
        for(unsigned int i=0;i<size;i++)
        {
            out << *ptr;
            ptr++;
        }
    }
    return result;
}

template <class T>
bool read_object(std::fstream& in, T& object)
{
    bool result=false;
    T* ptr;
    T swap_temp;
    const unsigned long size=sizeof(object);
    char temp[size];
    std::streampos pos;
    if(in.good())
    {
        pos=in.tellg();
        if(pos!=-1)
        {
            result=true;
            for(unsigned long i=0; i<size; i++)
            {
                if(!in.good())
                {
                    result=false;
                    break;
                }
                else
                {
                    in >> temp[i];
                }
            }
        }
    }
    if(result==false)
    {
        in.seekg(pos);
    }
    else
    {
        ptr=(T*)temp;
        swap_temp=*ptr;
        object=swap_temp;
    }
    return result;
}

Но я столкнулся со следующими проблемами: -sizeof оператор просто возвращает размер всех полей, он не учитывает также данные, указанныевнутренние поля;-Если в классе есть указатель, то этот указатель может указывать на «неправильный» адрес памяти, (например), если я использую указатель, который указывает на строку в стиле C, в памяти, как только программа заканчивает, строка освобождается. Когда экземпляр программы запускается снова, эта область памяти может быть где угодно.

Этот метод неправильный, потому что, например, sizeof (string) с моим компилятором возвращает 4. Поэтому я предполагаю, что он использует указатель на символЯ на 32-битной машине), чтобы указать на выделенную строку в стиле C. Вероятно, она даже не отслеживает длину.Поэтому, если строка содержит 32 символа, я этого не замечаю, она просто копирует значение указателя.

1 Ответ

3 голосов
/ 31 марта 2012

Ваш подход не может работать, так как C ++ не знает java-подобных методов, таких как рефлексия, поэтому вы не можете различить указатели и другие члены.

То, что вы хотите, называется serialisazion , и вы можете использовать его с такими библиотеками, как Boost.Serialization ( Demo ).

Но даже тогда вы не можете написать общую функцию, вы должны определить ее специально для каждого объекта.

...