crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Чтение/Запись вектора указателей из/в файл
Not_Once
  опции профиля:
сообщение 13.3.2014, 18:24
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 13.3.2014
Пользователь №: 4076

Спасибо сказали: 0 раз(а)




Репутация:   0  


Доброго времени суток! Не судите строго - опыта мало. Вообщем, нужна помощь, уже в конец запутался. Весь проект, естественно тащить не буду, попытаюсь на примере.
Допустим, имею:
1) Класс Cube c разнородной информацией и де-/сериализатором для потока.
Раскрывающийся текст
class Cube
{
public:

    bool a;
    int  b;
    char c;
    
    friend QDataStream &operator<< (QDataStream &write, const Cube &cb);
    friend QDataStream &operator>> (QDataStream &read, Cube &cb);
};

QDataStream &operator<< (QDataStream &write, const Cube &cb)  //Сериализация
{
    write << cb.a;
    write << cb.b;
    write << cb.c;
    return write;
}

QDataStream &operator>> (QDataStream &read, Cube &cb)  //Десериализация
{
    read >> cb.a;
    read >> cb.b;
    read >> cb.c;
    return read;
}


2) Класс Data с объявленным вектором указателей на объекты Cube и методами записи/чтения в данных из/в файл
Раскрывающийся текст

class Data
{
public:

    QVector<Cube*>  *Data_Cubes; //Данные по кубам

    void save(QVector<Cube*>  *Cubes);//Запись в файл
    void load(QVector<Cube*>  *Cubes);//Чтение из файла
};

void Data::save(QVector<Abonent *> &Cubes)
{
    QFile File("Cube.dat");
    if(File.open(QIODevice::WriteOnly))
    {
        QDataStream write(&File);
        write << Cubes;  //В стандартной библиотеке сериализатор для QVector описан
    }
    //Проверки различные и выводы сообщений, касаемые файла и потока опустим
}

void Data::load(QVector<Abonent *> &Cubes)
{
    QFile File("Cube.dat");
    if(File.open(QIODevice::ReadOnly))
    {
        QDataStream read(&File);
        read >> Cubes;  //В стандартной библиотеке десериализатор для QVector описан
    }
    //Проверки различные и выводы сообщений, касаемые файла и потока опустим
}


3)В QDaraStream предусмотрены де-/сериализатор для QVector:
Раскрывающийся текст

template<typename T>
QDataStream& operator<<(QDataStream& s, const QVector<T>& v)
{
    s << quint32(v.size());
    for (typename QVector<T>::const_iterator it = v.begin(); it != v.end(); ++it)
        s << *it;
    return s;
}

template<typename T>
QDataStream& operator>>(QDataStream& s, QVector<T>& v)
{
    v.clear();
    quint32 c;
    s >> c;
    v.resize(c);
    for(quint32 i = 0; i < c; ++i) {
        T t;
        s >> t;
        v[i] = t;
    }
    return s;
}


4)Основное окно, с общей информацией, откуда вызываю запись и чтение данных
Раскрывающийся текст

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private:
    Ui::MainWindow *ui;
    
    Data    *Data_common;//Общие данные
};


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    
    Data_common = new Data;
    Data_common->load(*Data_common->Data_Cubes);//Чтение
}

MainWindow::~MainWindow()
{
    delete ui;
    Data_common->save(*Data_common->Data_Cubes);//Запись
    /// Есть ли необходимость в удалении указателя? (обнуление для избежания проблем)
    delete Data_common;
    Data_common=0;
}



При текущем варианте, данные пишутся и читаются в десериализаторе Cube, но сам вектор забивается последним объектом и программа вылетает. Я уже вконец запутался с указателями и объектами.
Вопрос: подскажите, что делаю не так?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 13.3.2014, 18:58
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


Я вот тоже в указателях иногда путаюсь. Но вот думаю что проблема может быть тут:
QVector<Cube*>  *Data_Cubes;


сделайте так:
QVector<Cube>  *Data_Cubes; // указатель на вектор который хранит хначения Cube
//или так
QVector<Cube*>  Data_Cubes; // вектор который хранит указатели на значения Cube
//или так
QVector<Cube>  Data_Cubes; // вектор который хранит значения Cube


правильный вариант зависит от того что вам надо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Not_Once
  опции профиля:
сообщение 13.3.2014, 19:37
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 13.3.2014
Пользователь №: 4076

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Trisch @ 13.3.2014, 19:58) *
сделайте так:
QVector<Cube>  *Data_Cubes; // указатель на вектор который хранит хначения Cube
//или так
QVector<Cube*>  Data_Cubes; // вектор который хранит указатели на значения Cube
//или так
QVector<Cube>  Data_Cubes; // вектор который хранит значения Cube


правильный вариант зависит от того что вам надо.


Спасибо за ответ :rolleyes:
Мне нужен именно Вектор Указателей, который будет хранить объекты Cube. А вот объектом:
QVector<Cube*>  Data_Cubes; // вектор который хранит указатели на значения Cube

или указателем:
QVector<Cube*>  *Data_Cubes; // указатель на вектор который хранит указатели на значения Cube

реализовывать - я не знаю.
Попробовал вариант с объектом (QVector<Cube*> Data_Cubes) - ничего не изменилось :unsure:
К сожалению ошибку допустил в описании проблемы, а именно класса Cube(для де-/сериализации подкладываю не объект Cube а указатель на него, того требует описанная де-/сериализация в QDatastream):

Раскрывающийся текст
class Cube
{
public:

    bool a;
    int  b;
    char c;
    
    friend QDataStream &operator<< (QDataStream &write, const Cube *cb);
    friend QDataStream &operator>> (QDataStream &read, Cube *cb);
};

QDataStream &operator<< (QDataStream &write, const Cube *cb)  //Сериализация
{
    write << cb->a;
    write << cb->b;
    write << cb->c;
    return write;
}

QDataStream &operator>> (QDataStream &read, Cube *cb)  //Десериализация
{
    read >> cb->a;
    read >> cb->b;
    read >> cb->c;
    return read;
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 14.3.2014, 8:02
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


сериализация не работает с указателями. хранить указатели в файле - это безумие. сериализация работает только с объектами. поэтому сериализовать/десериализовать нужно сами объекты, а массив указателей создавать параллельно этому процессу, добавляя указатели на десериализованные объекты по мере их создания.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Not_Once
  опции профиля:
сообщение 14.3.2014, 16:40
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 13.3.2014
Пользователь №: 4076

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 14.3.2014, 9:02) *
сериализация не работает с указателями. хранить указатели в файле - это безумие. сериализация работает только с объектами. поэтому сериализовать/десериализовать нужно сами объекты, а массив указателей создавать параллельно этому процессу, добавляя указатели на десериализованные объекты по мере их создания.


Огромное спасибо! :clapping:
Переделаю - отпишусь.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
liamm
  опции профиля:
сообщение 26.4.2014, 21:30
Сообщение #6


Новичок


Группа: Новичок
Сообщений: 1
Регистрация: 26.4.2014
Пользователь №: 4113

Спасибо сказали: 0 раз(а)




Репутация:   0  


У меня тоже была необходимость сериализовать вектор указателей (назовем его QVector<SomeClass*> myVector), решение выглядит так:

class SomeClass{
  private:
    QString mSomeField;
  public:
    SomeClass();
  
    friend QDataStream &operator>>(QDataStream &in, SomeClass *inp);  
    friend QDataStream &operator<<(QDataStream &out, const SomeClass *inp);

};


операторы для сериализации/десериализации объекта по указателю:

QDataStream &operator<<(QDataStream &out, const SomeClass *inp){ //сериализация данных в поток
    out<<inp->mSomeField;
    return out;
}
QDataStream &operator>>(QDataStream &in, SimpleParam *inp){ //десериализация из потока
    in>>inp->mSomeField;
    return in;
}


сериализация вектора (сначала записываем в поток число элементов, потом данные для самих элементов)
 QVector<SomeClass*> myVector;
  ....
QDataStream inFile(&writeFile);

    inFile<<myVector.size();
    for(int i=0; i<myVector.size(); i++){
         inFile<<myVector[i];
    }


десериализация вектора (сначала вытаскиваем число элементов, потом данные для самих элементов, и заполняем на их основе вектор) :
QVector<SomeClass*> myVector;

QDataStream outFile(&readFile);
    int size=0;
    outFile>>size;
    for(int i=0; i<size; i++){
        SomeClass *item=new SomeClass();
        outFile>>item;
        myVector.append(item);
    }
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 22:13