Форум программистов, компьютерный форум, киберфорум
Boost C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30

Boost_serialization

06.10.2014, 20:16. Показов 997. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Правильно ли я понимаю что boost/serialization не позволяете сериализовать вектор из указателей на базовый класс?

C++
1
2
3
4
5
class A{/* код класса, включая код сериализации*/};
class B: public A {/*...*/}
class C: public A {/*...*/}
 
std::vector<A*> v; /* тут могут хранится указатели на A, B, C */
0
Лучшие ответы (1)
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
06.10.2014, 20:59
Avazart, Точно помню, что позволяет. Только слегка сложнее.
http://www.boost.org/doc/libs/... index.html
Сначала читаем это, а я попробую вспомнить как правильно это реализовать.
Вспомнил: http://www.boost.org/doc/libs/... edpointers читаем тут и вообще все, ибо полезная инфа.

Добавлено через 16 минут
Простенький пример: http://coliru.stacked-crooked.... e4bb54d929
1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.10.2014, 21:51  [ТС]
Ну я сразу вышел на первую ссылку, успел накатать такой код:
Код
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
class A
{
    public:
        A(){};
        A(std::string name):name_(name){}
        virtual ~A(){}
 
        std::string name(){ return name_; };
 
        virtual std::string description(){ return name_; }
 
    private:
 
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive &ar,const unsigned int version)
        {
             ar & name_;
        }
 
        std::string name_;
};
 
class B: public A
{
    public:
        B():A(){}
        B(std::string name,int intValue)
             :A(name),
             intValue_(intValue)
        {}
 
        std::string description()
        {
         std::stringstream ss;
         ss<< name() <<" "<<intValue_;
         return ss.str();
        }
 
        int intValue(){ return intValue_; }
 
    private:
 
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive &ar,const unsigned int version)
        {
             ar & boost::serialization::base_object<A>(*this);
             ar & intValue_;
        }
 
        int intValue_;
};
 
 
class C: public A
{
    public:
        C():A(){}
        C(std::string name,double doubleValue)
         : A(name),
             doubleValue_(doubleValue)
        {}
 
        std::string description()
        {
            std::stringstream ss;
            ss<< name() <<" "<<doubleValue_;
            return ss.str();
        }
 
        double doubleValue(){ return doubleValue_; }
 
    private:
 
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive &ar,const unsigned int version)
        {
             ar & boost::serialization::base_object<A>(*this);
             ar & doubleValue_;
        }
 
        double doubleValue_;
};
 
void save()
{
    std::ofstream file("archiv.txt");
    boost::archive::text_oarchive oa(file);
 
    A* a= new A("A1");
    oa<<a;
    delete a;
 
    /*В*/  A* b= new B("B1",10);
    oa<<b;
    delete b;
}
 
void load()
{
    std::ifstream file("archiv.txt");
    boost::archive::text_iarchive ia(file);
 
    A* a;
    ia>>a;
    std::cout<< a->description()<<std::endl;
    delete a;
 
    B* b;
    ia>>b;
    std::cout<< b->description()<<std::endl;
    delete b;
}
 
int main()
{
    save();
    load();
 
    getchar();
    return 0;
}

А вот описание register_type не видел.

Добавлено через 21 минуту
Добавил register_type

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
void save()
{
    std::ofstream file("archiv.txt");
    boost::archive::text_oarchive oa(file);
 
    //oa.register_type<A>();  ???
    oa.register_type<B>();
    oa.register_type<C>();
 
    A* a= new A("A1");
    oa<<a;
    delete a;
 
    A* b= new B("B1",10);
    oa<<b;
    delete b;
 
    A* c= new C("C1",3.14);
    oa<<c;
    delete c;
}
 
void load()
{
    std::ifstream file("archiv.txt");
    boost::archive::text_iarchive ia(file);
 
 // ia.register_type<A>();  ???
    ia.register_type<B>();
    ia.register_type<C>();
 
    A* a;
    ia>>a;
    std::cout<< a->description()<<std::endl;
    delete a;
 
    B* b;
    ia>>b;
    std::cout<< b->description()<<std::endl;
    delete b;
 
    C* c;
    ia>>c;
    std::cout<< c->description()<<std::endl;
    delete c;
}
Получаю неадекватный вывод:
A1
B1 10
3.14
Т.е. "C1" cъело...
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
06.10.2014, 23:01
Лучший ответ Сообщение было отмечено Убежденный как решение

Решение

Avazart, Ищите в чем проблема... http://coliru.stacked-crooked.... c63cd3fad6 выводит

A1
B1 10
C1 3.14
П.С. при сейве, на удаление указателя ровно после записи получал исключение pointer_conflict, поэтому перенес в конец функции.
1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.10.2014, 23:20  [ТС]
Цитата Сообщение от ForEveR Посмотреть сообщение
П.С. при сейве, на удаление указателя ровно после записи получал исключение pointer_conflict, поэтому перенес в конец функции.
Да похоже в этом была проблема. Вероятно в реальном коде нужно использовать смарт поинтеры чтобы такое не наблюдать.
Тестил в С++BuilderXE3 он не ругался на удаление, нужно будет как нибудь в MSVC попробовать.

Да и обязательно регистрировать базовый класс?

Добавлено через 7 минут
Я заглянул в файл и не увидел там имени классов, так что вероятно сохраняется какой нибудь индекс определяющий тип класса, из чего вероятно можно предположить что индексы могут зависеть от порядка регистрации классов, а значит могут быть проблемы при чтении/сохранении данных разными программами из одного файла, так ?
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
06.10.2014, 23:26
Avazart, Нет, необязательно.
Как там сохраняется - детали реализации, не более того. Какие могут быть проблемы, конкретнее пожалуйста.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.10.2014, 00:40  [ТС]
Цитата Сообщение от ForEveR Посмотреть сообщение
Как там сохраняется - детали реализации, не более того.
Оно то так но во первых интересно что там под капотом, во вторых что под капотом определяет возможные проблемы.
Цитата Сообщение от ForEveR Посмотреть сообщение
Какие могут быть проблемы, конкретнее пожалуйста.
Если полагаться на предположение что boost записывает id класса(в порядке регистрации классов, к примеру) то к примеру A=0, B=1, C=2 то очевидно что эти значения должны(ну и порядок регистрации) совпадать в разных приложения которые должны иметь возможность работать с одним файлом. Иначе что записало в файл одно приложение не сможет прочитать другое.

Добавлено через 1 час 3 минуты
Можно проделать такой тест с моим кодом:
1. Запустить программу что бы создался файл и закрыт программу.
2. Закомментировать строчку с ф-цией save() что бы при следующем запуске программы только читались предыдущие данные с файла

C++
1
2
3
4
5
int main()
{
    //save();
    load();
// ...
А затем сменить порядок регистрации классов в функции load();

C++
1
2
ia.register_type<C>();
ia.register_type<B>();
И перекомпилировать/запустить программу- лично у меня выбивает ошибку при чтении, думаю это подтверждает мое предположение.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
07.10.2014, 10:44
Avazart, Возможно. Не все в этом жизни идеально. Можете посмотреть на то как это действительно реализовано в сорцах буста.

Добавлено через 36 минут
В общем и целом все именно так:

C++
1
2
3
4
5
6
7
8
9
inline const basic_oarchive_impl::cobject_type &
basic_oarchive_impl::register_type(
    const basic_oserializer & bos
){
    cobject_type co(cobject_info_set.size(), bos);
    std::pair<cobject_info_set_type::const_iterator, bool>
        result = cobject_info_set.insert(co);
    return *(result.first);
}
Где cobject_type
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    struct cobject_type
    {
        const basic_oserializer * m_bos_ptr;
        const class_id_type m_class_id;
        bool m_initialized;
        cobject_type(
            std::size_t class_id,
            const basic_oserializer & bos
        ) :
            m_bos_ptr(& bos),
            m_class_id(class_id),
            m_initialized(false)
        {}
        // ...
    }
А cobject_info_set

C++
1
2
    typedef std::set<cobject_type> cobject_info_set_type;
    cobject_info_set_type cobject_info_set;
Так что да, порядок регистрации имеет значение.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru