Форум программистов, компьютерный форум, киберфорум
Boost C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/43: Рейтинг темы: голосов - 43, средняя оценка - 4.53
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562

boost::serialization

21.07.2011, 15:41. Показов 8879. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нечто вроде ДБ написано с использованием boost::any (любой конечный элемент ДБ, то есть содержимое любой ячейки - объект Holder в котором используется boost::any). Захотелось мне это дело сериализовать, а то как-то не коммильфо.

База довольно простая и ограничения на ней - используется только два типа. Числа (int) или строки (string).

Как бы поаккуратнее сериализовать объект boost::any (save/load)?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.07.2011, 15:41
Ответы с готовыми решениями:

boost::serialization
Рассматривал тему boost::serialization. И в примере ниже моя студия выкидывает много ошибок. Можете пожалуйста подсказать в чем бида ...

boost::serialization
Хотел бы узнать, есть ли преимущество в записи файла с boost::serialization перед обычной записью?

serialized via boost::serialization
Как можно считать информацию с файла в вектор, при этом не зная заранее его размерность. В фукнции save() я записываю в файл n человек, а...

10
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
21.07.2011, 18:14
Цитата Сообщение от ForEveR Посмотреть сообщение
Как бы поаккуратнее сериализовать объект boost::any (save/load)?
поаккуратней в сравнении с каким способом?
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
21.07.2011, 19:08  [ТС]
niXman, Я имею ввиду адекватно, чтобы работало. Пробовал через исключения - то есть пробуем преобразовать в int -> не вышло значит пробуем в string и сереализуем, вышло -> сериализуем int.
При загрузке это было намного проблемнее -> грузим в int -> не вышло -> грузим в string, вышло -> грузим в int и устанавливаем значение внутреннего any потом понял что подход в корне не верен, ибо получал ошибку архива, что и понятно.

Пробовал загружать все в строку, затем переводить в int lexical_cast-ом -> тоже потерпел неудачу, в строку грузится все что есть в строке файла (?), итого при попытке сериализовать три числа 5, 25, 15 и загрузки их в строку получил строку 5, 25, 15 и в дальнейшем вылет программы с ошибкой архива, ибо читаю/пишу я вектор таких Holder-ов.

Идей как-то практически нет как успешно это сделать.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
21.07.2011, 19:18
возможно логичнее в БД хранить все как строки?
1
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
22.07.2011, 07:22
Вот сам себе головняк создал. У тебя же всего два известных типа, зачем boost::any, почему не boost::variant?
В принципе, ты же сам пишешь не интрузивную сериализацию. Что тебе мешает сперва сохранить информацию о действительном типе? Тогда при загрузке обойдёшься простым свитчем.
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
22.07.2011, 10:13  [ТС]
niXman, Возможно логичнее да. Возможно так и поступлю.

Deviaphan, Ну пока два... А потом может расширить захочу... Ну да. Тоже вариант

Добавлено через 1 час 37 минут
Вообщем разрешил с сериализацией примерно так.

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
        template<class Archive>
        void save(Archive& arch, const unsigned int version) const
        {
            std::string result;
            try
            {
                result = boost::any_cast<std::string>(value_);
            }
            catch (const std::exception& e)
            {
                if (type_ == int_)
                {
                    int value = boost::any_cast<int>(value_);
                    result = boost::lexical_cast<std::string>(value);
                }
                else if (type_ == string_)
                { 
                    result = boost::any_cast<std::string>(value_);    
                }
                else
                {
                }
            }
            arch & result;
            arch & type_;
        }
        template<class Archive>
        void load(Archive& arch, const unsigned int version)
        {
            std::string result;
            arch & result;
            arch & type_;
            if (type_ == int_)
            {
                try
                {
                    value_ = boost::any(boost::lexical_cast<int>(result));
                }
                catch (const std::exception& e)
                {
                    value_ = boost::any(result);
                }
            }
            else if (type_ == string_)
            {
                value_ = boost::any(result);
            }
            else
            {
            }
        }
Небольшая магия, т.к. название колонки так же является Holder-ом и хранит в себе тип, но не string как было бы наверное логичнее, а тип данных столбца.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
22.07.2011, 10:43
Т.е. в пределах столбца типы одинаковые? Тогда не мути! Сохраняй кортежами, построчно.
Тогда тебе будет нужно один раз распарсить типы данных для каждого столбца, и потом уже по порядку известные типы сериализовывать.
Нынешний вариант никуда не годен, просто представь, какая лапша и рай-кэтчей у тебя получится при добавлении новых типов.

Самое объектно-ориентированное решение - не хранить данные непосредственно, а использовать сериализуемую обёртку, вместо boost::any. Полиморфные классы без проблем сериализуются. Чуть больше писанины, зато от переключения типов избавишься. 21 век, всё таки, уже.
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
22.07.2011, 14:28  [ТС]
Deviaphan, Вариант. Буду пробовать.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
06.09.2011, 13:47  [ТС]
Вернулся к этому. Видимо буду делать как-то так.

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
#include <string>
#include <fstream>
#include <iostream>
 
#include <boost/serialization/string.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/any.hpp>
#include <boost/lexical_cast.hpp>
 
namespace serial = boost::serialization;
namespace arch = boost::archive;
 
class Base_Ser
{
public:
    Base_Ser(const std::string& type):type_(type)
    {
    }
    virtual ~Base_Ser()
    {
    }
    virtual boost::any getValue() const = 0;
    virtual std::string getString() const = 0;
    friend class serial::access;
private:
    template<class T>
    void serialize(T& ar, const unsigned int version = 0)
    {
        ar & type_;
    }
    std::string type_;
};
 
class Int_Ser:public Base_Ser
{
public:
    explicit Int_Ser(int value = 0):Base_Ser("Integer"), value_(value)
    {
    }
    virtual ~Int_Ser()
    {
    }
    boost::any getValue() const {return boost::any(value_);}
    std::string getString() const {return boost::lexical_cast<std::string>(value_);}
    friend class serial::access;
private:
    template<class T>
    void serialize(T& ar, const unsigned int version = 0)
    {
        ar & serial::base_object<Base_Ser>(*this);
        ar & value_;
    }
    int value_;
};
 
class String_Ser:public Base_Ser
{
public:
    explicit String_Ser(const std::string& value = std::string()):Base_Ser("String"), value_(value)
    {
    }
    virtual ~String_Ser()
    {
    }
    boost::any getValue() const {return boost::any(value_);}
    std::string getString() const {return value_;}
    friend class serial::access;
private:
    template<class T>
    void serialize(T& ar, const unsigned int version = 0)
    {
        ar & serial::base_object<Base_Ser>(*this);
        ar & value_;
    }
    std::string value_;
};
 
typedef std::vector<Base_Ser*> ser_objects;
 
size_t save(const ser_objects& serial, const std::string& f_name)
{
    std::ofstream ofs(f_name.c_str());
    arch::text_oarchive oarch(ofs);
    oarch.register_type(static_cast<Int_Ser*>(NULL));
    oarch.register_type(static_cast<String_Ser*>(NULL));
    oarch << serial;
    return serial.size();
}
 
ser_objects load(const std::string& f_name, size_t size)
{
    std::ifstream ifs(f_name.c_str());
    arch::text_iarchive iarch(ifs);
    iarch.register_type(static_cast<Int_Ser*>(NULL));
    iarch.register_type(static_cast<String_Ser*>(NULL));
    ser_objects objects;
    iarch >> objects;
    return objects;
}
 
int main()
{
    ser_objects objs;
    objs.push_back(new String_Ser("Hello!"));
    objs.push_back(new Int_Ser(5));
    std::for_each(objs.begin(), objs.end(), [](Base_Ser* obj) {std::cout << obj->getString() << std::endl;});
    size_t size = save(objs, "ser_test.dat");
    std::for_each(objs.begin(), objs.end(), [](Base_Ser* obj) {delete obj;});
    std::cout << "Save successfull. Size: " << size << std::endl;
    ser_objects new_objs = load("ser_test.dat", size);
    std::for_each(new_objs.begin(), new_objs.end(), [](Base_Ser* obj) {std::cout << obj->getString() << std::endl;});
    std::for_each(new_objs.begin(), new_objs.end(), [](Base_Ser* obj) {delete obj;});
}
Единственное - не нравится насчет register_type. Есть другой вар?
1
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
06.09.2011, 14:01
Цитата Сообщение от ForEveR Посмотреть сообщение
Есть другой вар?
Тоже этим вопросом задавался. Причины понять вроде смог, а вот как избавиться - нет.

Добавлено через 55 секунд
А другой вариант, это вручную назначать каждому типу свой идентификатор и поприветствовать переключение типов.)
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
06.09.2011, 15:49  [ТС]
Лучший ответ Сообщение было отмечено ForEveR как решение

Решение

В итоге:

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
namespace my_serialization
{
 
class Base
{
public:
    explicit Base(const std::string& type):type_(type)
    {
    }
    virtual ~Base() 
    {
    }
    std::string getType() const {return type_;}
    virtual std::string asString() const = 0;
    virtual boost::any asAny() const = 0;
    friend class serialization::access;
private:
    template<class Arch>
    void serialize(Arch& ar, const unsigned int version = 0)
    {
        ar & type_;
    }
    std::string type_;
};
 
template<class T>
class Template:public Base
{
public:
    explicit Template(const T& value = T()):Base(typeid(T).name()), value_(value)
    {
    }
    virtual ~Template()
    {
    }
    virtual std::string asString() const 
    {
        return boost::lexical_cast<std::string>(value_);
    }
    virtual boost::any asAny() const 
    {
        return value_;
    }
    friend class serialization::access;
private:
    template<class Arch>
    void serialize(Arch& ar, const unsigned int version = 0)
    {
        ar & value_;
    }
    T value_;
};
 
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
typedef boost::shared_ptr<my_serialization::Base> value_pointer;
 
        template<class Arch>
        void serialize(Arch& ar, const unsigned int version = 0)
        {
            ar.register_type(static_cast<my_serialization::Template<std::string>*>(0));
            ar.register_type(static_cast<my_serialization::Template<int>*>(0));
            ar & type_;
            ar & value_;
        }
        value_pointer value_;
        types_ type_;
Добавлено через 56 минут
В сериализации Template забыл добавить сериализацию объекта базового класса.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.09.2011, 15:49
Помогаю со студенческими работами здесь

Boost::serialization, как сериализовать std::tuple?
В принципе вопрос в теме. Как именно?

Как подключить Boost::serialization в CMakeLists.txt?
Если кто-то работал с таким и готов помочь, то спасибо)

boost serialization. загрузка данных из архива в std::list
День добрый, возникла небольшая проблема. Я сохраняю данные в архив используя #include&lt;boost/serialization/list.hpp&gt; ...

boost::serialization. Как сериальзовывать собственные типы данных?
Как с помощью буста сериализовать следующий класс? class data{ private: std::string Name; std::string Type; unsigned...

boost serialization. Перегрузка save_construct_data и load_constract_data для шаблонных классов
Добрый вечер, снова сериализация и снова проблема. Нужно сериализовать шаблонный класс без конструктора по умолчанию. Ниже приведен...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru