GGym's Practice Notes

4-2. 프로토타입_직렬화 본문

Design Pattern/Modern C++ 디자인패턴

4-2. 프로토타입_직렬화

GGym_ 2020. 4. 17. 21:29

책에서는 직렬화도 소개한다. (모던CPP디자인패턴/https://book.naver.com/bookdb/book_detail.nhn?bid=14742427)

직렬화는 어떠한 객체 데이터를 비트의 나열로 만들어 파일로 저장하거나 네트워크로 전송할 수 있게 하는것을 말한다.

직렬화를 사용하면 객체복제를 쉽게 할 수 있게 만든다. 객체를 비트열로 나타내고 역직렬화를 통해 모든 정보와 내부 구성요소들을 복구 할 수 있다. 이 작업은 복제작업과 동일하다.

C++은 아쉽게도 직렬화를 표준으로 지원하지 않는다. Boost 라이브러리를 사용하여 지원하지만 나는 라이브러리나 코드생성기의 도움 없이 코드를 구현하고 싶다...

 

전체 코드 : 

#include<iostream>
#include<memory>

#include<boost/serialization/access.hpp>
#include<boost/archive/text_oarchive.hpp>
#include<boost/archive/text_iarchive.hpp>
using namespace std;
using namespace boost;

struct Address{
    string street, city;
    int suite;
    Address(const string& street, const string& city, const int suite)
        : street{street}, city{city}, suite{suite}{}
        
    Address(const Address& address)
        : street{address.street}, city{address.city}, suite{address.suite}{}
        
    friend ostream& operator<<(ostream& os, const Address& obj){
        return os << "street: " << obj.street
                  << " city: " << obj.city
                  << " suite: " << obj.suite;
    }
private:
    friend class boost::serialization::access;
    template<class Ar> void serialize(Ar& ar, const unsigned int version){
        ar & street;
        ar & city;
        ar & suite;
    }
};

struct Contact{
    string name;
    Address* address;  

    Contact() : name(nullptr), address(nullptr){}
    Contact(const Contact& other)
        : name{name}{
        address = new Address(*other.address);
    }
    Contact& operator=(const Contact& other){
        if(this == &other)
            return *this;
        name = other.name;
        address = other.address;
        return *this;
    }
    Contact(const string name, Address* address)
        : name{name}, address{address}{
    }
    friend ostream& operator<<(ostream& os, const Contact& obj){
        return os << "name: " << obj.name
                  << " address: " << *obj.address;
    }
    ~Contact(){
        delete address;
    }
private:
    friend class boost::serialization::access;
    template<class Ar> void serialize(Ar& ar, const unsigned int version){
        ar & name;
        ar & address;
    }
};
int main(){
    Contact worker{"", new Address("123 East Dr", "London", 0)};
    Contact john{worker}; // or Contact john = worker;
    john.name = "John Doe";
    john.address->suite = 10;

    auto clone = [](const Contact& c){
        ostringstream oss;
        boost::archive::text_oarchive oa(oss);
        oa << c;
        string s = oss.str();

        istringstream iss(oss.str());
        boost::archive::text_iarchive ia(iss);
        Contact result;
        ia >> result;
        return result;
    };

    Contact jane = clone(john);
    jane.name = "Jane Doe";
    jane.address->street = "138B West Dr";
    jane.address->suite = 300;

    cout << john << endl << jane << endl;

    return 0;
}