0
votes

i'm currently working on boost serialization and I came into a moment when I can't really move forward. I have a class Order which holds pointers to Table and Waiter classes. I would like to add just that serialization for all the other classes works perfectly fine, its just order that makes problems. When I try to serialize Order in my main, I get an exemption: Unhandled exception at 0x77A03FC8 in ConsoleApplication1.exe: Microsoft C++ exception: boost::archive::archive_exception at memory location 0x0081C42C. and + e {m_buffer=0x0081c6f4 "unregistered class - derived class not registered or exported" code=unregistered_class (2) } const boost::archive::archive_exception & Have you got an idea how to make this connection work properly in serialization call?

Order.h
#pragma once
#include <vector>
#include <string>
#include <iostream>
#include <ctime>    
#include "Meal.h"
#include "Table.h"
#include "Waiter.h"
using namespace std;
enum Status { ASSIGNED, PROCESSED, CONFIRMED, SUBMITTED, BEING_PREPARED, READY, SERVED, CANCELED, PAID, FINALIZED };


class Order
{
private:
friend std::ostream & operator<<(std::ostream &os, const Order  &tb);
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */) {
    ar & ID & TimeAndDate & status & table & waiter & meals;
};
protected:


string TimeAndDate;
Status status;
Table * table;
Waiter * waiter;
string ID;

public:
typedef Meal * Meal_Pointer;
list<Meal_Pointer> meals;
Order(string,Table*,Waiter*);

Order():table(new Table),waiter(new Waiter) {};
string CurrentDateAndTime();
void UpdateStatus(Status);
void AssignWaiter(Waiter*);
void AssignTable(Table*);
void AddItem(Meal*);
void append(Meal *_bs)
{
    meals.insert(meals.end(), _bs);
}

};

Order.cpp

#include "Order.h"


Order::Order(string id, Table* tab, Waiter* wait)
:ID(move(id)), table(tab), waiter(wait), status(ASSIGNED), 







std::ostream & operator<<(std::ostream &os, const Order &tb)
{
//std::list<Meal *>::const_iterator it;
// note: we're displaying the pointer to permit verification
// that duplicated pointers are properly restored.

return os << ' ' << tb.ID << ' ' << tb.TimeAndDate << ' ' << tb.status << '      ' << tb.table << ' ' << tb.waiter << ' ' ;

/*for (it = tb.meals.begin(); it != tb.meals.end(); it++) {
    os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
}*/
}

template void Order::serialize<boost::archive::text_iarchive>(
boost::archive::text_iarchive & ar,
const unsigned int file_version
);
template void Order::serialize<boost::archive::text_oarchive>(
boost::archive::text_oarchive & ar,
const unsigned int file_ver

Functions

void save_order(const Order &s, const char * filename) {
// make an archive
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
oa << s;
}
int main ()
{
filename = "order.txt";

save_order(myOrder, filename.c_str());
Order neworder;
restore_order(neworder, filename.c_str());}
1
I like the way you name your parameters (_bs!). - sehe

1 Answers

0
votes

You don't show the relevant code.

The code you do show is messy and broken.

Here I've fixed it enough so it can compile:

Live On Coliru

Obviously, no problem.

// Order.h
//#pragma once
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/string.hpp>
#include <ctime>
#include <fstream>
#include <iostream>

using namespace std;

struct Table {};
struct Waiter {};
struct Meal {};

namespace boost { namespace serialization {
    template <typename Ar> void serialize(Ar&, Table&, unsigned) { }
    template <typename Ar> void serialize(Ar&, Waiter&, unsigned) { }
    template <typename Ar> void serialize(Ar&, Meal&, unsigned) { }
} }

enum Status { ASSIGNED, PROCESSED, CONFIRMED, SUBMITTED, BEING_PREPARED, READY, SERVED, CANCELED, PAID, FINALIZED };

class Order {
  private:
    friend std::ostream &operator<<(std::ostream &os, const Order &tb);
    friend class boost::serialization::access;
    template <class Archive> void serialize(Archive &ar, const unsigned int /* file_version */) {
        ar &ID &TimeAndDate &status &table &waiter &meals;
    }

  protected:
    string TimeAndDate;
    string ID;
    Table *table;
    Waiter *waiter;
    Status status;
    typedef Meal *Meal_Pointer;
    list<Meal_Pointer> meals;

  public:
    Order(string, Table *, Waiter *);
    Order() : table(new Table), waiter(new Waiter){};

    string CurrentDateAndTime();
    void UpdateStatus(Status);
    void AssignWaiter(Waiter *);
    void AssignTable(Table *);
    void AddItem(Meal *);
    void append(Meal *_bs) { meals.insert(meals.end(), _bs); }
};

// Order.cpp

//#include "Order.h"

Order::Order(string id, Table *tab, Waiter *wait) : ID(move(id)), table(tab), waiter(wait), status(ASSIGNED) {}
std::ostream &operator<<(std::ostream &os, const Order &tb) {
    return os << ' ' << tb.ID << ' ' << tb.TimeAndDate << ' ' << tb.status << ' ' << tb.table << ' ' << tb.waiter
              << ' ';

    /*for (it = tb.meals.begin(); it != tb.meals.end(); it++) {
        os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
    }*/
}

template void Order::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive &ar, const unsigned int file_version);
template void Order::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive &ar, const unsigned int file_ver);

void save_order(const Order &s, const char *filename) {
    // make an archive
    std::ofstream ofs(filename);
    boost::archive::text_oarchive oa(ofs);
    oa << s;
}

void restore_order(Order &s, const char *filename) {
    std::ifstream ifs(filename);
    boost::archive::text_iarchive ia(ifs);
    ia >> s;
}

int main() {
    std::string const filename = "order.txt";

    {
        Order myOrder;
        save_order(myOrder, filename.c_str());
    }

    std::cout << std::ifstream(filename).rdbuf() << "\n";

    {
        Order neworder;
        restore_order(neworder, filename.c_str());
    }
}

Hints

What you seem to be doing is serializing polymorphic instances of classes (e.g. derived from Table, Waiter or Meal). In such cases you need to register the derived classes and serialize the base properly: