C ++에서 클래스를 직렬화 및 역 직렬화 할 수 있습니까?
C ++에서 클래스를 직렬화 및 역 직렬화 할 수 있습니까?
나는 3 년 동안 Java를 사용해 왔으며 직렬화 / 역 직렬화는 그 언어에서 매우 사소한 것입니다. C ++에는 비슷한 기능이 있습니까? 직렬화를 처리하는 기본 라이브러리가 있습니까?
예가 도움이 될 것입니다.
Boost::serialization
라이브러리는 오히려 우아하게이 문제를 처리합니다. 여러 프로젝트에서 사용했습니다. 사용 방법을 보여주는 예제 프로그램이 있습니다 ( here) .
이를 수행하는 유일한 기본 방법은 스트림을 사용하는 것입니다. 그것은 본질적으로 모든 Boost::serialization
라이브러리가하는 것입니다. 텍스트와 같은 형식으로 객체를 작성하고 동일한 형식으로 읽도록 프레임 워크를 설정하여 스트림 방법을 확장합니다.
대한 유형, 또는 당신의 자신의 종류의 내장 operator<<
과 operator>>
제대로 매우 간단 그 정의; 자세한 내용 은 C ++ FAQ 를 참조하십시오.
나는 이것이 오래된 게시물이라는 것을 알고 있지만 검색 할 때 가장 먼저 올라온 것 중 하나입니다 c++ serialization
.
C ++ 11에 액세스 할 수있는 사람이라면 누구나 바이너리, JSON 및 XML을 즉시 지원하는 직렬화를위한 C ++ 11 헤더 전용 라이브러리 인 cereal을 살펴 보는 것이 좋습니다 . 시리얼은 확장하고 사용하기 쉽게 설계되었으며 Boost와 비슷한 구문을 가지고 있습니다.
부스트는 좋은 제안입니다. 그러나 자신만의 롤을 원한다면 그렇게 어렵지 않습니다.
기본적으로 객체 그래프를 작성한 다음 구조화 된 스토리지 형식 (JSON, XML, YAML 등)으로 출력하는 방법이 필요합니다. 그래프 재귀 괜찮은 객체 알고리즘을 사용하고 표시된 모든 객체를 출력하는 것처럼 간단하게 그래프를 작성합니다.
기초적인 (그러나 여전히 강력한) 직렬화 시스템을 설명하는 기사를 작성했습니다. 당신은 찾을 수 있습니다 그것은 흥미로운 : 온 디스크 파일 형식, 제 2 부로 SQLite는 사용 .
지금까지와 같은 "내장"라이브러리 이동합니다 <<
및 >>
직렬화를 위해 특별히 예약되어있다.
<<
객체를 직렬화 컨텍스트 (일반적으로 iostream
) 로 출력 >>
하고 해당 컨텍스트에서 데이터를 다시 읽으 려면 재정의해야합니다 . 각 개체는 집계 된 자식 개체를 출력합니다.
이 방법은 객체 그래프에 사이클이없는 한 제대로 작동합니다.
그렇다면, 그러한주기를 처리하기 위해 라이브러리를 사용해야합니다.
Google 프로토콜 버퍼를 권장 합니다 . 새 프로젝트에서 라이브러리를 테스트 할 기회가 있었고 사용하기가 매우 쉽습니다. 라이브러리는 성능에 크게 최적화되어 있습니다.
Protobuf는 객체를 직렬화하지 않고 사양에 따라 직렬화되는 객체에 대한 코드를 생성한다는 점에서 여기에 언급 된 다른 직렬화 솔루션과 다릅니다.
Boost :: serialization 은 훌륭한 옵션이지만, 훨씬 더 우아한 시리얼 이라는 새로운 프로젝트가 발생했습니다 ! 나는 그것을 조사하는 것이 좋습니다.
amef 프로토콜을 확인할 수 있습니다. amef 에서 C ++ 인코딩의 예는 다음과 같습니다.
//Create a new AMEF object
AMEFObject *object = new AMEFObject();
//Add a child string object
object->addPacket("This is the Automated Message Exchange Format Object property!!","adasd");
//Add a child integer object
object->addPacket(21213);
//Add a child boolean object
object->addPacket(true);
AMEFObject *object2 = new AMEFObject();
string j = "This is the property of a nested Automated Message Exchange Format Object";
object2->addPacket(j);
object2->addPacket(134123);
object2->addPacket(false);
//Add a child character object
object2->addPacket('d');
//Add a child AMEF Object
object->addPacket(object2);
//Encode the AMEF obejct
string str = new AMEFEncoder()->encode(object,false);
자바의 디코딩은 다음과 같습니다.
string arr = amef encoded byte array value;
AMEFDecoder decoder = new AMEFDecoder()
AMEFObject object1 = AMEFDecoder.decode(arr,true);
프로토콜 구현에는 C ++과 Java 용 코덱이 있으며 흥미로운 부분은 이름 값 쌍의 형태로 객체 클래스 표현을 유지할 수 있다는 것입니다.이 프로젝트에서 우연히 우연히 발견되었을 때 마지막 프로젝트에서 비슷한 프로토콜이 필요했습니다. 내 요구 사항에 따라 기본 라이브러리를 수정했습니다. 이것이 도움이되기를 바랍니다.
다른 포스터에서 설명한대로 부스트 직렬화를 사용하는 것이 좋습니다. 다음은 부스트 자습서를 훌륭하게 보완하는 사용법에 대한 자세한 자습서입니다. http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-serialization/
Sweet Persist 는 또 다른 하나입니다.
It is possible to serialize to and from streams in XML, JSON, Lua, and binary formats.
I suggest looking into Abstract factories which is often used as a basis for serialization
I have answered in another SO question about C++ factories. Please see there if a flexible factory is of interest. I try to describe an old way from ET++ to use macros which has worked great for me.
ET++ was a project to port old MacApp to C++ and X11. In the effort of it Eric Gamma etc started to think about Design Patterns. ET++ contained automatic ways for serialization and introspection at runtime.
If you want simple and best performance and don't care about backward data compatibility, try HPS, it's lightweight, much faster than Boost, etc, and much easier to use than Protobuf, etc.
Example:
std::vector<int> data({22, 333, -4444});
std::string serialized = hps::serialize_to_string(data);
auto parsed = hps::parse_from_string<std::vector<int>>(serialized);
Here is a simple serializer library I knocked up. It's header only, c11 and has examples for serializing basic types. Here's one for a map to class.
https://github.com/goblinhack/simple-c-plus-plus-serializer
#include "c_plus_plus_serializer.h"
class Custom {
public:
int a;
std::string b;
std::vector c;
friend std::ostream& operator<<(std::ostream &out,
Bits my)
{
out << bits(my.t.a) << bits(my.t.b) << bits(my.t.c);
return (out);
}
friend std::istream& operator>>(std::istream &in,
Bits my)
{
in >> bits(my.t.a) >> bits(my.t.b) >> bits(my.t.c);
return (in);
}
friend std::ostream& operator<<(std::ostream &out,
class Custom &my)
{
out << "a:" << my.a << " b:" << my.b;
out << " c:[" << my.c.size() << " elems]:";
for (auto v : my.c) {
out << v << " ";
}
out << std::endl;
return (out);
}
};
static void save_map_key_string_value_custom (const std::string filename)
{
std::cout << "save to " << filename << std::endl;
std::ofstream out(filename, std::ios::binary );
std::map< std::string, class Custom > m;
auto c1 = Custom();
c1.a = 1;
c1.b = "hello";
std::initializer_list L1 = {"vec-elem1", "vec-elem2"};
std::vector l1(L1);
c1.c = l1;
auto c2 = Custom();
c2.a = 2;
c2.b = "there";
std::initializer_list L2 = {"vec-elem3", "vec-elem4"};
std::vector l2(L2);
c2.c = l2;
m.insert(std::make_pair(std::string("key1"), c1));
m.insert(std::make_pair(std::string("key2"), c2));
out << bits(m);
}
static void load_map_key_string_value_custom (const std::string filename)
{
std::cout << "read from " << filename << std::endl;
std::ifstream in(filename);
std::map< std::string, class Custom > m;
in >> bits(m);
std::cout << std::endl;
std::cout << "m = " << m.size() << " list-elems { " << std::endl;
for (auto i : m) {
std::cout << " [" << i.first << "] = " << i.second;
}
std::cout << "}" << std::endl;
}
void map_custom_class_example (void)
{
std::cout << "map key string, value class" << std::endl;
std::cout << "============================" << std::endl;
save_map_key_string_value_custom(std::string("map_of_custom_class.bin"));
load_map_key_string_value_custom(std::string("map_of_custom_class.bin"));
std::cout << std::endl;
}
Output:
map key string, value class
============================
save to map_of_custom_class.bin
read from map_of_custom_class.bin
m = 2 list-elems {
[key1] = a:1 b:hello c:[2 elems]:vec-elem1 vec-elem2
[key2] = a:2 b:there c:[2 elems]:vec-elem3 vec-elem4
}
참고URL : https://stackoverflow.com/questions/234724/is-it-possible-to-serialize-and-deserialize-a-class-in-c
'Programing' 카테고리의 다른 글
AngularJS에 뷰 / 부분 특정 스타일을 포함하는 방법 (0) | 2020.06.30 |
---|---|
파이썬으로 BDD 연습하기 (0) | 2020.06.30 |
Google Code Subversion 저장소를 GitHub에 포크 및 동기화 (0) | 2020.06.30 |
WordPress에서는 어떤 유형의 해시를 사용합니까? (0) | 2020.06.30 |
작업 사본에서 버전없는 / 무시 된 파일 / 폴더를 모두 삭제하려면 어떻게해야합니까? (0) | 2020.06.29 |