Форум программистов, компьютерный форум, киберфорум
Наши страницы

Boost C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
#1

Буст сериализация. указатель на абстрактный базовый класс без конструктора по умолчанию - Boost C++

20.03.2013, 20:10. Просмотров 1264. Ответов 8
Метки нет (Все метки)

Читая документацию по сериализации с помощью буста запутался. Ситуация следующая. Имеется виртуальный базовый класс в Base.h:

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
#ifndef BASE_H
#define BASE_H
 
 
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include<new>
 
 
//declare the derived class
class base;
 
//declare new save and load function for non-defualt constructor
namespace boost {
    namespace serialization {
 
        template<class Archive>
            inline void load_construct_data(Archive & ar, test::base* t, const unsigned int file_version);
        template<class Archive>
            inline void save_construct_data(Archive & ar, const test::base* t, const unsigned int file_version);
 
    }
}
 
 
class Base{
   private:
         int a;
         int b;
         int c;
         //зафрендим сохранение и загрузку
        template<class Archive> friend 
              void boost::serialization::load_construct_data(Archive & ar, derived * t, const unsigned int file_version);
    template<class Archive> friend 
              void boost::serialization::save_construct_data(Archive & ar, const derived* t, const unsigned int file_version);
        friend class boost::serialization::access;
 
   public:
         //конструктор не по умолчанию
          Base(int a_, int b_, int c_): a(a_), b(b_), b(b_) {};
          virtual ~Base();
          virtual Foo() = 0;
 
 
};
 
//new load and save functions
namespace boost{
    namespace serialization {
        template<class Archive>
 
                    inline void load_construct_data(Archive & ar, Base* t, const unsigned int file_version)
                    {
                        
                        int a_;
                        int b_;
                        int с_;
                        ar >> a_;
                        ar >> b_;
                                                ar >> с_;
                        :: new(t) Base(a_,b_, с_);
                    }
        template<class Archive>
 
                    inline void save_construct_data(Archive & ar,const Base* t, const unsigned int file_version)
                    {
 
                        ar << t->a;
                        ar << t->b;
                        ar << t->с;
                        
                    }
    
 
    }
}
#endif
Имеется класс-наследник в derived.h:

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
#ifndef DERIVED_H
#define DERIVED_H
 
 
 
#include"Base.h"
#include <boost/serialization/base_object.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
 
 
class derived : public Base{
   private:
      friend class boost::serialization::access;
      template <typename Archive>
      void serialize(Archive& ar, const unsigned version) {
               ar & boost::serialization::base_object<Base>(*this);
      }
   public:
       //constructor
    derived (int a, int b):Base(a,b,3) {};
    
        //virtual function from the base class
    int getN() {return 1;};
 
 
};
 
#endif
И все это выполняется в main.cpp:
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
#include<fstream>
#include<iostream>
#include"derived.h"
#include"Base.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
 
 
int main(){
   //Initialize some variables
   int a = 3, b = 4;
   //input and output files
   std::ofstream ofs("output.txt");
   std::ifstream ifs("output.txt");
    
   //new object of <derived> type 
   Base *A = new derived(a,b);
   
   //save the A
   {
    boost::archive::text_oarchive oa(ofs);
    // write class instance to archive
    oa << A;
    // archive and stream closed when destructors are called
        std::cout<<"DONE WRITING";
   }
   
   //что делать тут? добавлять констурктор по умолчанию в derived, чтобы это выглядело так? а потом подгружать данные из архива
   Base *B = new derived();
   {
    boost::archive::text_iarchive ia(ifs);
    // write class instance to archive
    ia >> B;
    // archive and stream closed when destructors are called
        std::cout<<"DONE READING";
   }
 
 
 
}
и вот теперь главные вопросы:
  1. Нужно ли переписывать load_construct_data и save_construct_data для базового типа как показано в примере кода, или это делать в наследнике?
  2. Какой объект создавать в load_construct_data: Base (по идее создать не получится, так как это виртуальный класс, но нам же как то нужно сериализовать этот тип) или derived (перенеся функцию load в соотеветствующий файл)?
  3. При чтение из архива какой объект создавать и как?
  4. ну и в общем...верна ли данная идея сериализации?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.03.2013, 20:10
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Буст сериализация. указатель на абстрактный базовый класс без конструктора по умолчанию (Boost C++):

Указатель на абстрактный шаблонный класс - C++
Есть абстрактный шаблон класса и 3 производных от него шаблонов классов. Так же есть шаблонная функция, в которую нужно передать указатель...

Абстрактный класс без виртуальных функций - C++
Мне нужен класс без виртуальных функций, но чтобы его нельзя было создать. Можно ли такое реализовать?

Создание объекта через указатель на базовый абстрактный класс - C++
Есть абстрактный класс, от него наследуется 3 класса. В программе предусмотрено создание нового объекта(добавление клиента страховой...

Не имеющий конструктора без параметров базовый класс (аргументов) не разрешает плодить наследников - C#
Здравствуйте, никак не могу понять, в чём проблема. Возникла необходимость переопределить аргументы для BackgroundWorker'а в DoWork, но...

Класс: Создать абстрактный базовый класс Figure с виртуальными методами вычисления площади и периметра. - C++
Создать абстрактный базовый класс Figure с виртуальными методами вычисления площади и периметра. Создать производные классы: Rectangle...

абстрактный базовый класс - C++
Создать абстрактный базовый класс с виртуальной функцией – объем. Создать производные классы: параллелепипед, пирамида, шар со своими...

8
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
22.03.2013, 13:08 #2
А зачем создавать базовый? По идее как раз load/save для базового не играют ровно никакой роли. Потому load/save data для Derived-ов и все. + регистрация в архиве derived классов. Таким образом получается

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
#include <boost/serialization/serialization.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/shared_ptr.hpp>
 
#include <sstream>
 
namespace serialization = boost::serialization;
namespace archive = boost::archive;
 
class Base
{
   friend class boost::serialization::access;
   template<typename Archive>
   void serialize(Archive& ar, const unsigned int)
   {
      ar & f;
   }
public:
   Base(int i) : n(i), f(0) {}
   virtual ~Base() = 0;
   int n;
   int get() const { return f; }
private:
   int f;
};
 
Base::~Base() {}
 
class Derived : public Base
{
   friend class boost::serialization::access;
   template<typename Archive>
   void serialize(Archive& ar, const unsigned int)
   {
      ar & boost::serialization::base_object<Base>(*this);
   }
public:
   Derived(int n, int t) : Base(n), z(t) {}
   int z;
};
 
class Derived2 : public Base
{
   friend class boost::serialization::access;
   template<typename Archive>
   void serialize(Archive& ar, const unsigned int)
   {
      ar & boost::serialization::base_object<Base>(*this);
   }
public:
   Derived2(int n) : Base(n) {}
};
 
namespace boost { namespace serialization {
template<typename Archive>
inline void save_construct_data(Archive& ar, const Derived* b, const unsigned int)
{
   ar << b->n;
   ar << b->z;
}
 
template<typename Archive>
inline void load_construct_data(Archive& ar, Derived* b, const unsigned int)
{
   int n = 0, z = 0;
   ar >> n;
   ar >> z;
   ::new(b) Derived(n, z);
}
 
template<typename Archive>
inline void save_construct_data(Archive& ar, const Derived2* b, const unsigned int)
{
   ar << b->n;
}
 
template<typename Archive>
inline void load_construct_data(Archive& ar, Derived2* b, const unsigned int)
{
   int n = 0;
   ar >> n;
   ::new(b) Derived2(n);
}
 
}}
 
int main()
{
   {
   std::stringstream ss;
   archive::text_oarchive oarch(ss);
   oarch.register_type<Derived>();
   Base* b = new Derived(1, 5);
   oarch << b;
   delete b;
   Derived* ptr;
   archive::text_iarchive iarch(ss);
   iarch >> ptr;
   std::cout << ptr->n << " " << ptr->z << " " << ptr->get() << std::endl;
   delete ptr;
   }
   {
   std::stringstream ss;
   archive::text_oarchive oarch(ss);
   oarch.register_type<Derived2>();
   Base* b = new Derived2(10);
   oarch << b;
   delete b;
   Derived2* ptr2;
   archive::text_iarchive iarch(ss);
   iarch >> ptr2;
   std::cout << ptr2->n << " " << ptr2->get() << std::endl;
   delete ptr2;
   }
}
С выделением памяти при сериализации в указатель заморачиться не нужно, судя по всему буст корректно выделяет память через
C++
1
operator new(size_t)
1
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
22.03.2013, 13:29  [ТС] #3
Спасибо.
А если мы немного модифицируем Base, так что для конструктора нам надо будет вторую переменную записать в private f. Тогда f надо будет все равно записывать через Base, или и в Base, и в save_cunstuct_data через геттер для derived2?

C++
1
2
3
4
5
6
7
8
9
10
11
12
class Base { 
     friend class boost::serialization::access; 
     
     template<typename Archive> void serialize(Archive& ar, const unsigned int) 
    { ar & f; } 
     public: 
         Base(int i, int j) : n(i), f(j) {} 
         virtual ~Base() = 0; int n; 
         int get() const { return f; } 
     private: 
          int f; 
  };

и соответственно

C++
1
2
3
4
5
6
7
8
9
10
11
class Derived2 : public Base
{
   friend class boost::serialization::access;
   template<typename Archive>
   void serialize(Archive& ar, const unsigned int)
   {
      ar & boost::serialization::base_object<Base>(*this);
   }
public:
   Derived2(int n, int f) : Base(n, f) {}
};

тогда для того чтобы сохранить derived2, нам надо будет уже использовать геттер для f?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<typename Archive>
inline void save_construct_data(Archive& ar, const Derived2* b, const unsigned int)
{
   ar << b->n;
   ar << b->get();
}
 
template<typename Archive>
inline void load_construct_data(Archive& ar, Derived2* b, const unsigned int)
{
   int n = 0;
   int f = 0;
   ar >> n;
   ar >> f;
 
   ::new(b) Derived2(n,f);
}
я правильно понял?
0
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
22.03.2013, 13:50 #4
sl_k, В load_construct_data точно. И в save очевидно тоже. Как-то ведь сконструировать объект надо
0
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
22.03.2013, 16:58  [ТС] #5
ForEveR, Это то да, но тогда в derived2 save_construct_data мы записываем f через get(), и в добавок еще в базовом классе в процедуре serialize. не запишется ли f дважды таким образом?
0
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
22.03.2013, 18:26 #6
sl_k, Что-то мне подсказывает, что в базовом классе эту функцию стоит оставить пустой.
1
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
22.03.2013, 19:14  [ТС] #7
ForEveR, не хочет компилятор со мной по хорошему работать, даже если save_construct_data друг для Derived2 и get() - public у Base:

Bash
1
2
3
4
5
In function ‘void boost::serialization::save_construct_data(Archive&, const Derived2*, unsigned int)’:
error: no matching function for call to ‘Derived2::get() const’
note: candidate is:
const int Base::get() <near match>
no known conversion for implicit ‘this’ parameter from ‘const Derived2*’ to ‘Base*
0
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
22.03.2013, 19:16 #8
sl_k, Ну резонно же. Почему get функция не константная?
1
sl_k
12 / 12 / 0
Регистрация: 15.04.2010
Сообщений: 61
22.03.2013, 19:43  [ТС] #9
Добавлено через 3 минуты
Ну и финильная модификация save для переменной f, и компилятор приветствует меня завершением сборки

C++
1
2
3
4
5
6
7
8
template<typename Archive>
inline void save_construct_data(Archive& ar, const Derived2* b, const unsigned int)
{
   ar << b->n;
   int f;
   f = b->get();
   ar << f;
}
0
22.03.2013, 19:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.03.2013, 19:43
Привет! Вот еще темы с ответами:

Абстрактный базовый класс - C++
Создать абстрактный базовый класс с виртуальной функцией - объем. Создать производные классы: параллелепипед, пирамида, тетраэдр, шар со...

Абстрактный базовый класс - C++
У меня имеется свой некоторый класс, для которого переопределена куча операций, в том числе и операторы + - * /, преподаватель дал задание...

Абстрактный базовый класс - C++
Привет всем! У меня есть абстрактный базовый класс Object.Он содержит различные методы. Например, virtual void...

абстрактный базовый класс - C++
люди подскажите.есть абстрактный базовый класс можно ли в нем определить конструктор копирования? написал в компиляторе,получается,что...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru