C++ 클래스 객체를 stream으로 통신 및 전달방법 - Boost Serialization(1) [직렬화된 클래스 만들기]

공대생의 팁 2018.10.20 17:36


 객체지향의 언어를 사용함에 있어 가장 큰 장점으로 class를 사용하여 Constructor나 Inheritance(상속)등을 사용할 수 있어 프로그래밍을 하는 데 있어 한결 더 편리해진다는 점입니다.


 물론 Object(객체)를 하나의 프로그래밍에서만 사용한다면 큰 어려움이 없으나 Object를 binary 파일로 저장한다던가 통신 등을 통해 다른 프로세스로 전달을 해야할 경우 이를 stream으로 전달하여야 하나 이는 int나 float와 같은 Primitive 변수만 전달될 수 있다는 단점이 있습니다.


 이를 해결한 방법으로서 Object를 Serialization(직렬화)하여 stream으로 Object의 값을 전달하거나 저장할 수 있게 된 것입니다.


https://commons.wikimedia.org/


 Serialization을 하는 이유는 자신이 가지고 있는 Object가 상대에게는 어떤 방식으로 표현되어 있는지 알 수 없기 때문에 이를 전달하기 전에 Object가 가지고 있는 값을 직렬화시켜 Object의 값을 받고자 하는 쪽에서 분별할 수 있게 만들어줍니다. 직렬화 된 값이 상대에게 도착한 후에는 이를 다시 역직렬화(Deserialization)를 거쳐 자신이 갖고 있었던 Object값으로 다시 만들어줍니다. 즉, '4'나 'c'와 같이 간단하게 구성된 값이나 글자를 받을 수 있도록 만드는 것을 직렬화(Serialization)이라 할 수 있습니다.


 C++ 라이브러리 또한 객체를 사용하기 때문에 이를 지원할 수 있는 Boost 라이브러리를 지원합니다. 이를 사용하기 위해 다음과 같이 설치합니다.


$ sudo apt install libboost-all-dev


 다음으로 아래와 같은 간단한 예제를 통해 Boost의 Serialization의 방식에 대해 이해해보도록 합니다.


class_fileio.cc

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
 
#include<iostream>
#include<fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
 
using namespace std;
 
class tst{
public:
    friend class boost::serialization::access;
 
    tst(string sName, int sage, float spi)
        :Name(sName), age(sage), pi(spi)
    {}
 
    tst(){
    }
 
    string Name;
    int age;
    float pi;
 
    template<class Archive>
    void serialize(Archive& ar, const unsigned int version){
        ar & Name;
        ar & age;
        ar & pi;
    }
 
 
};
 
 
int main(){
 
    tst T("Tab", 31, 3.1415);
    tst* pT = new tst("Bat", 13, 2.5);
 
    ofstream output("output.txt", ios::binary);
 
    boost::archive::text_oarchive oa(output);
    oa << T;
    output.close();
 
    ifstream input("output.txt", ios::binary);
    boost::archive::text_iarchive ia(input);
 
    tst TT;
    ia >> TT;
 
    cout << TT.Name << endl;
    cout << TT.age << endl;
    cout << TT.pi << endl;
 
    ofstream pout("pout.txt", ios::binary);
    boost::archive::text_oarchive poa(pout);
    poa << pT;
    pout.close();
 
    ifstream pin("pout.txt", ios::binary);
    boost::archive::text_iarchive pia(pin);
 
    tst* pTT;
    pia >> pTT;
 
    cout << pTT->Name << endl;
    cout << pTT->age << endl;
    cout << pTT->pi << endl;
 
    return 0;
}
cs


다음으로 위의 작성된 코드를 컴파일합니다.


g++ class_fileio.cc -lboost_serialization


 실행하면 다음과 같은 결과를 확인하실 수 있습니다.



 결과를 보면 알 수 있듯이 Class의 값이 포인터인 경우에도 동작이 잘 수행되고 있음을 직접 확인하실 수 있습니다. 이제 자신이 만든 클래스로도 stream을 통해 전송할 수 있음을 확인할 수 있습니다!