简体   繁体   中英

Deserialize an object using c++ boost library

I am trying to deserialize my Command object using the boost library. My goal is obviously to get the serialized object and pass it through the deserializer. My class:

class Command {
private:

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive& arch, const unsigned int version)
    {
        arch& letter;
        arch& x;
        arch& y;
        arch& button;
    }
    char letter;
    int x;
    int y;
    std::string button;

public:
    Command(char _letter, int _x, int _y, std::string _button) {
        letter = _letter;
        x = _x;
        y = _y;
        button = _button;
    }
    Command() {}
    ~Command() {}

    char getLetter() { return letter; }
    int getX() { return x; }
    int getY() { return y; }
    std::string getButton() { return button; }

    void printCommand() {
        std::cout << "letter: " << letter << std::endl;
        std::cout << "x     : " << x << std::endl;
        std::cout << "y     : " << y << std::endl;
        std::cout << "button: " << button << std::endl;
        std::cout << "================" << std::endl;
    }

};

I used the boost library to serialize the object using this code:

template <class T>
std::string serialize(T obj) {
    std::ofstream ofs("output");
    {
        boost::archive::text_oarchive oa(ofs);
        oa << obj;
    }
    return "output";
}

Since I am sending those serialized objects through a TCP server, I need to serialize them but the deserialization code I use doesn't work:

template <class T>
T deSerialize(std::string s) {

    T t = T();
    std::ifstream ifs(s);
    boost::archive::text_iarchive ia(ifs);
    ia >> t;
    return t;
}

I think my understanding of the process is lacking so I can't seem to understand why it doesn't work.

I can't really tell. Perhaps because your example is not selfcontained. So let me help you:

Live On Coliru

#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 <fstream>
#include <iostream>

class Command {
  private:
    friend class boost::serialization::access;
    template <class Archive> void serialize(Archive& arch, unsigned) {
        arch& letter& x& y& button;
    }

    char        letter;
    int         x;
    int         y;
    std::string button;

  public:
    Command(char _letter = '\0', int _x = 0, int _y = 0,
            std::string_view _button = {})
        : letter(_letter)
        , x(_x)
        , y(_y)
        , button(_button)
    { }

    char        getLetter() const { return letter; }
    int         getX()      const { return x;      }
    int         getY()      const { return y;      }
    std::string getButton() const { return button; }

    friend std::ostream& operator<<(std::ostream& os, Command const& cmd){
        return os << "letter: " << cmd.letter << "\n" //
                  << "x     : " << cmd.x << "\n"      //
                  << "y     : " << cmd.y << "\n"      //
                  << "button: " << cmd.button << "\n";
    }
};

template <class T> void my_save(T const& obj, std::string fileName)
{
    std::ofstream ofs(fileName);
    boost::archive::text_oarchive oa(ofs);
    oa << obj;
}

template <class T> T my_load(std::string fileName)
{
    std::ifstream ifs(fileName);
    boost::archive::text_iarchive ia(ifs);

    T result;
    ia >> result;
    return result;
}

int main() {
    using Commands = std::vector<Command>;
    my_save(Commands {
        {'s', 10, 20, "Save"},
        {'q', 21, 31, "Quit"},
        {'l', 32, 42, "Load"},
        {'x', 43, 53, "Exit"},
    }, "output.txt");

    for (auto&& cmd : my_load<Commands>("output.txt"))
        std::cout << "-----\n" << cmd;
}

Prints

-----
letter: s
x     : 10
y     : 20
button: Save
-----
letter: q
x     : 21
y     : 31
button: Quit
-----
letter: l
x     : 32
y     : 42
button: Load
-----
letter: x
x     : 43
y     : 53
button: Exit

And output.txt contains something like

22 serialization::archive 19 0 0 4 0 0 0 115 10 20 4 Save 113 21 31 4 Quit 108 32 42 4 Load 120 43 53 4 Exit

Simplify

It strikes me that Command resembles a Java-esque quasi-class (PDF) . I'd probably simplify: Live On Coliru

struct Command {
    void serialize(auto& ar, unsigned) { ar& letter& x& y& button; }

    char        letter = '\0';
    int         x = 0, y = 0;
    std::string button;

    friend std::ostream& operator<<(std::ostream& os, Command const& cmd) {
        return os << "['" << cmd.letter << "'," << cmd.x << "," << cmd.y << ","
                  << std::quoted(cmd.button) << "]";
    }
};

Output

['s',10,20,"Save"]
['q',21,31,"Quit"]
['l',32,42,"Load"]
['x',43,53,"Exit"]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM