С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
21 / 4 / 2
Регистрация: 05.07.2015
Сообщений: 126
1

Сериализация custom обьектов, которые имеют общего родителя и поле другого класса

15.02.2016, 01:14. Показов 1941. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Подскажите пожалуйста, как мне правильно записать информацию с vector в файл, объектами vector являются кастомные классы - в моем случае это 3 класса которые имеют общего родителя, у них также есть поле класса Time, которое почему-то не корректно записывается,,, и соответственно считываются,
//родительский класс
C++
1
2
3
4
5
6
7
8
9
10
11
12
class Goods
{
protected:
    string name;
    int pieces;
    string productionCountry;
    Time expireDate;
    string unitOfMeasure;
public:
virtual ostream& serialize(ostream& os)=0;
    virtual istream& unserialize(istream& is)=0;
}
//класс потомок
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class OfficeStuff:public Goods
{
public:
    ostream& serialize(ostream& os);
    istream& unserialize(istream& is);
}
ostream& OfficeStuff::serialize(ostream& os) 
{
        int l = name.length();
        os.write((const char *) &pieces, sizeof(pieces));
        os.write((const char *) &l, sizeof(size_t));
        os.write(name.c_str(), name.length());
        int P = productionCountry.length();
        os.write((const char *) &P, sizeof(size_t));
        os.write(productionCountry.c_str(), productionCountry.length());
        int U = unitOfMeasure.length();
        os.write((const char *) &U, sizeof(size_t));
        os.write(unitOfMeasure.c_str(), unitOfMeasure.length());
    return os;
}
 
istream& OfficeStuff::unserialize(istream& is) 
{
    int l;
    is.read((char *) &pieces, sizeof(pieces));
    if(! is.eof()) 
    {
        is.read((char *) &l, sizeof(size_t));
        if (! is.eof()) 
        {
            char* n = new char[l];
            is.read(n, l);
            name.assign(n,l);
            delete n;
            n = new char[l];
            is.read(n, l);
            productionCountry.assign(n,l);
            delete n;
            n = new char[l];
            is.read(n, l);
            unitOfMeasure.assign(n,l);
            delete n;
        }
    }
    return is;
}
//Time

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Time
{
    int year;
    int month;
    int day;
public:
    ostream& serialize(ostream& os);
    istream& unserialize(istream& is);
}
ostream& Time::serialize(ostream& os) 
{
    os.write((const char *) &year, sizeof(year));
    os.write((const char *) &month, sizeof(month));
    os.write((const char *) &day, sizeof(day));
    return os;
}
 
istream& Time::unserialize(istream& is) 
{
    int l;
    is.read((char *) &year, sizeof(year));
    is.read((char *) &month, sizeof(month));
    is.read((char *) &day, sizeof(day));
 
    return is;
}
Запись в файл:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ofstream off( "office.txt", std::ios::binary );
    if( off.is_open() )
    {
        for(vector<OfficeStuff>::iterator itr = officeStuff.begin(); itr != officeStuff.end() ; ++itr)
        {
            itr->serialize(off);
            
        }
        off.close();
    } 
    else
    {
        printf( "Can't put data in office.txt'\n");
    }
Заранее спасибо за помощь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.02.2016, 01:14
Ответы с готовыми решениями:

XmlJava. Сериализация класса с полем - массивом объектов другого класса
Есть 2 класса Студент и Академ.группа(с полем - массивом студентов). Необходимо выполнить...

Linq to Xml запрос, где обьект имеет List обьектов другого класса
есть классы public class Worker { public List&lt;EducationDuringWorking&gt;...

Массив объектов одного класса как поле другого класса
Доброе время суток. Мне тут в универе задали лабу, нужно создать класс полем которого будет массив...

Поле класса содержит массив объектов другого класса
Добрый день. Есть класс Queue,который как поле содержит массив объектов на класс Pers. public...

16
Эксперт С++
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
15.02.2016, 01:24 2
Цитата Сообщение от Melany Посмотреть сообщение
Подскажите пожалуйста, как мне правильно
как то так:
Поясните по сериализации

можно ещё глянуть в сторону cereal
http://uscilab.github.io/cereal/
1
21 / 4 / 2
Регистрация: 05.07.2015
Сообщений: 126
15.02.2016, 01:32  [ТС] 3
hoggy, да, у нас одинаковое задание с этим товарищем)) только меня boost не интересует, я хочу свою реализацию сделать,,,
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
15.02.2016, 02:02 4
Цитата Сообщение от Melany Посмотреть сообщение
у них также есть поле класса Time, которое почему-то не корректно записывается,,, и соответственно считываются,
Где оно записывается и считывается?
1
21 / 4 / 2
Регистрация: 05.07.2015
Сообщений: 126
15.02.2016, 02:07  [ТС] 5
nd2, я не знаю как написать запись объекта класса, я только прописала в самом Time как нужно записываться, а вот как заставить сам Time в поле данного класса записаться - этого я не знаю, плюс int не корректно сериализуется, со string все в порядке,,,
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
15.02.2016, 02:12 6
Цитата Сообщение от Melany Посмотреть сообщение
int l = name.length();
//...
os.write((const char *) &l, sizeof(size_t));
Лучше что-то одно: или int, или size_t, или sizeof(l).

Добавлено через 2 минуты
Цитата Сообщение от Melany Посмотреть сообщение
а вот как заставить сам Time в поле данного класса записаться
Как-то, так:
C++
1
expireDate.serialize(os);
Цитата Сообщение от Melany Посмотреть сообщение
плюс int не корректно сериализуется
В Time или в OfficeStuff?
1
21 / 4 / 2
Регистрация: 05.07.2015
Сообщений: 126
15.02.2016, 02:15  [ТС] 7
nd2, в OfficeStuff
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
15.02.2016, 02:16 8
Цитата Сообщение от Melany Посмотреть сообщение
в OfficeStuff
Может быть из-за этого:
Цитата Сообщение от nd2 Посмотреть сообщение
Лучше что-то одно: или int, или size_t, или sizeof(l).
1
21 / 4 / 2
Регистрация: 05.07.2015
Сообщений: 126
15.02.2016, 02:25  [ТС] 9
nd2, нет, по всей видимости я не так сериализую инты, со Временем тоже проблемы,,,

Добавлено через 5 минут
string одни отображаются корректно, все остальное - мусор,,,
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
15.02.2016, 02:38 10
Цитата Сообщение от Melany Посмотреть сообщение
string одни отображаются корректно, все остальное - мусор,,,
Где отображаются? В файле?
1
21 / 4 / 2
Регистрация: 05.07.2015
Сообщений: 126
15.02.2016, 02:39  [ТС] 11
да в файле,
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
15.02.2016, 02:41 12
Лучший ответ Сообщение было отмечено Melany как решение

Решение

Если в файле блокнотом смотришь, то int-ы, при бинарной записи, и должны выглядеть мусором.

Добавлено через 57 секунд
Правильность записи проверяется чтением, а не разглядыванием содержимого файла (тем более бинарного).
1
21 / 4 / 2
Регистрация: 05.07.2015
Сообщений: 126
15.02.2016, 02:57  [ТС] 13
Да, тут я конечно сглупила)), А можете помочь со считыванием, а то я как-то слабо понимаю что тут происходит)) я этот кусочек кода с похожего примера взяла, но что-то не могу все склеить под свой вариант,,,

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Warehouse::LoadDataFromFile()
{
 
    char fileName[20]= "construct.txt";
    std::ifstream ifs( fileName, std::ios::binary );
    if( ifs.is_open() )
    {
        while(! .read(ifs).eof())
        {
            ConstructMaterials obj;
            cout<<(obj.SetName).c_str()<<" "<<(obj.SetPieces())<<endl;
            ifs.close();
        }
    else
    {
        printf( "Can't get data from '%s'\n", fileName );
    }
 
 
}
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
15.02.2016, 03:07 14
У тебя же есть чтение (только для поля Time нужно добавить)?
1
21 / 4 / 2
Регистрация: 05.07.2015
Сообщений: 126
15.02.2016, 03:15  [ТС] 15
Time - добавила: expireDate.unserialize(is);

Добавлено через 4 минуты
а как с общим считыванием? Если объектов несколько и их надо закинуть в вектор? В таком варианте я правильно считываю данные?
C++
1
2
3
4
5
6
7
8
9
10
11
12
    char fileName[20]= "construct.txt";
    ifstream ifs( fileName, std::ios::binary );
    if( ifs.is_open() )
    { 
        ConstructMaterials obj;
    while(! obj.unserialize(ifs).eof())
        {
            constructMaterials.push_back(obj);
            //cout<<obj.SetName()<<" "<<(obj.SetPieces())<<endl;
            ifs.close();
        }
    }
в таком варианте считывает только первый обьект и то не все поля - дату также - отображает только месяц- string...
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
15.02.2016, 03:47 16
Лучший ответ Сообщение было отмечено Melany как решение

Решение

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
class Time
{
    int year;
    int month;
    int day;
public:
    ostream& serialize(ostream& os);
    istream& unserialize(istream& is);
 
    void set(int y, int m, int d)
    {
        year = y; month = m; day = d;
    }
 
    void show()
    {
        cout << year << ' ' << month << ' ' << day << endl;
    }
};
 
class Goods
{
protected:
    int pieces;
    string name;
    string productionCountry;
    Time expireDate;
    string unitOfMeasure;
public:
virtual ostream& serialize(ostream& os)=0;
    virtual istream& unserialize(istream& is)=0;
};
 
class OfficeStuff:public Goods
{
public:
    ostream& serialize(ostream& os);
    istream& unserialize(istream& is);
    void show()
    {
        cout << pieces << endl;
        cout << name << endl;
        cout << productionCountry << endl;
        expireDate.show();
        cout << unitOfMeasure << endl;
    }
    void set(int p, string n, string pr, int ty, int tm, int td, string unit)
    {
        pieces = p;
        name = n;
        productionCountry = pr;
        expireDate.set(ty, tm, td);
        unitOfMeasure = unit;
    }
};
 
ostream& OfficeStuff::serialize(ostream& os) 
{
        
        os.write((const char *) &pieces, sizeof(pieces));
        int l = name.length();
        os.write((const char *) &l, sizeof(l));
        os.write(name.c_str(), name.length());
        int P = productionCountry.length();
        os.write((const char *) &P, sizeof(P));
        os.write(productionCountry.c_str(), productionCountry.length());
        
        expireDate.serialize(os);
        
        int U = unitOfMeasure.length();
        os.write((const char *) &U, sizeof(U));
        os.write(unitOfMeasure.c_str(), unitOfMeasure.length());
        return os;
}
 
istream& OfficeStuff::unserialize(istream& is) 
{
    if(is.read((char *) &pieces, sizeof(pieces))) 
    {
        int l;
        is.read((char *) &l, sizeof(l));
        char* n = new char[l];
        is.read(n, l);
        name.assign(n, l);
        delete n;
        is.read((char *) &l, sizeof(l));
        n = new char[l];
        is.read(n, l);
        productionCountry.assign(n,l);
        delete n;
            
        expireDate.unserialize(is);
        
        is.read((char *) &l, sizeof(l));   
        n = new char[l];
        is.read(n, l);
        unitOfMeasure.assign(n,l);
        delete n;
    }
    return is;
};
 
ostream& Time::serialize(ostream& os) 
{
    os.write((const char *) &year, sizeof(year));
    os.write((const char *) &month, sizeof(month));
    os.write((const char *) &day, sizeof(day));
    return os;
}
 
istream& Time::unserialize(istream& is) 
{
    //int l;
    is.read((char *) &year, sizeof(year));
    is.read((char *) &month, sizeof(month));
    is.read((char *) &day, sizeof(day));
 
    return is;
}
 
////////////////////////////////////////////////////////////////////
 
int main()
{
    vector<OfficeStuff> officeStuff;
    OfficeStuff obj1;
    OfficeStuff obj2;
    obj1.set(1, "asdf", "qwer", 2, 3, 4, "zxcv");
    obj2.set(11, "aaasdf", "qqqwer", 22, 33, 44, "zzzxcv");
 
    officeStuff.push_back(obj1);
    officeStuff.push_back(obj2);
 
    for (auto it = officeStuff.begin(), end = officeStuff.end(); it != end; ++it)
    {
        it ->show();
        cout << endl;
    }
    
    ofstream off( "office.txt", std::ios::binary );
    if( off.is_open() )
    {
        for(vector<OfficeStuff>::iterator itr = officeStuff.begin(); itr != officeStuff.end() ; ++itr)
        {
            if (!itr->serialize(off))
                break;
        }
        off.close();
    } 
    else
    {
        printf( "Can't put data in office.txt'\n");
    }
 
    vector<OfficeStuff> v;
 
    ifstream in( "office.txt", std::ios::binary );
    if( in.is_open() )
    {
         OfficeStuff temp;
         while (temp.unserialize(in))
             v.push_back(temp);
         
         in.close();
    } 
    else
    {
        printf( "Can't get data in office.txt'\n");
    }
    
    
    for (auto it = v.begin(), end = v.end(); it != end; ++it)
    {
        it ->show();
        cout << endl;
    }
    
    system("pause");
    return 0;
}
1
21 / 4 / 2
Регистрация: 05.07.2015
Сообщений: 126
15.02.2016, 04:04  [ТС] 17
nd2, Спасибо огромное, сейчас буду разбираться,,,
0
15.02.2016, 04:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.02.2016, 04:04
Помогаю со студенческими работами здесь

Инициализация экземпляра класса, как поле другого класса
Всем доброго времени суток ! Есть класс: class a{ public: a(int _type): type(_type) {} ...

Поле класса - массив объектов другого класса
Здравствуйте. У меня определен класс Article, в котором определен конструктор по умолчанию. Затем...

XML сериализация java обьектов
Хочу сериализовать в файл свои компоненты - наследники JLabel, JButton и т.д. Когда делаю это по...

Создать в классе поле типа другого класса
Как создать в классе поле типа string? Я пишу просто string Name, но компилятор ругается.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru