Czy można serializować i deserializować klasę w C ++?
Używam Javy od 3 lat i serializacja / deserializacja jest dość trywialna w tym języku. Czy C ++ ma podobne funkcje? Czy istnieją biblioteki natywne, które obsługują serializację?
Przykład byłby pomocny.
c++
serialization
Agusti-N
źródło
źródło
Odpowiedzi:
Boost::serialization
Biblioteka obsługuje to raczej elegancko. Używałem go w kilku projektach. Oto przykładowy program pokazujący, jak go używać .Jedynym rodzimym sposobem jest użycie strumieni. To w zasadzie wszystko, co
Boost::serialization
robi biblioteka, rozszerza metodę strumieniową, konfigurując strukturę do zapisywania obiektów w formacie tekstowym i odczytywania ich z tego samego formatu.W przypadku typów wbudowanych lub własnych typów z odpowiednio zdefiniowanymi
operator<<
ioperator>>
odpowiednio zdefiniowanymi jest to dość proste; zobacz C ++ FAQ, aby uzyskać więcej informacji.źródło
Zdaję sobie sprawę, że to stary post, ale jest to jeden z pierwszych, który pojawia się podczas wyszukiwania
c++ serialization
.Zachęcam każdego, kto ma dostęp do C ++ 11, do przyjrzenia się zbożowi , bibliotece C ++ 11 tylko z nagłówkiem do serializacji, która obsługuje pliki binarne, JSON i XML po wyjęciu z pudełka. cereal został zaprojektowany tak, aby był łatwy w rozbudowie i użytkowaniu oraz miał podobną składnię do Boost.
źródło
Zwiększenie to dobra sugestia. Ale jeśli chcesz toczyć własne, nie jest to takie trudne.
Po prostu potrzebujesz sposobu na zbudowanie wykresu obiektów, a następnie wyprowadzenie ich do jakiegoś strukturalnego formatu przechowywania (JSON, XML, YAML, cokolwiek). Tworzenie wykresu jest tak proste, jak użycie algorytmu oznaczania rekurencyjnego przyzwoitego obiektu, a następnie wyprowadzenie wszystkich zaznaczonych obiektów.
Napisałem artykuł opisujący podstawowy (ale wciąż potężny) system serializacji. Może cię to zainteresować: Używanie SQLite jako formatu pliku na dysku, część 2 .
źródło
Jeśli chodzi o biblioteki „wbudowane”,
<<
i>>
zostały zarezerwowane specjalnie do serializacji.Należy przesłonić,
<<
aby wyprowadzić obiekt do jakiegoś kontekstu serializacji (zwykleiostream
) i>>
odczytać dane z powrotem z tego kontekstu. Każdy obiekt jest odpowiedzialny za wyprowadzanie swoich zagregowanych obiektów podrzędnych.Ta metoda działa dobrze, o ile graf obiektu nie zawiera cykli.
Jeśli tak, będziesz musiał skorzystać z biblioteki, aby poradzić sobie z tymi cyklami.
źródło
<<
operatory są używane do drukowania reprezentacji obiektów w postaci czytelnej dla człowieka, co bardzo często nie jest tym, czego chcesz do serializacji.<<
rodzajostream
, spróbuj zdefiniować go dla strumienia plików.<<
aby wyprowadzić swój obiekt do jakiegoś kontekstu serializacji… Każdy obiekt jest odpowiedzialny za wyprowadzenie swojego…” - pytanie dotyczy tego, jak uniknąć konieczności pracochłonnego pisania tego dla każdego obiektu: ile może język lub biblioteki pomagają?Polecam bufory protokołów Google . Miałem okazję przetestować bibliotekę w nowym projekcie i jest niezwykle łatwa w użyciu. Biblioteka jest mocno zoptymalizowana pod kątem wydajności.
Protobuf różni się od innych wymienionych tutaj rozwiązań serializacji w tym sensie, że nie serializuje twoich obiektów, ale raczej generuje kod dla obiektów, które są serializowane zgodnie ze specyfikacją.
źródło
Boost :: serializacja to świetna opcja, ale natknąłem się na nowy projekt: Cereal, który uważam za znacznie bardziej elegancki! Gorąco polecam zbadanie tego.
źródło
Możesz sprawdzić protokół amef , przykład kodowania C ++ w amef wyglądałby tak,
Dekodowanie w javie wyglądałoby następująco:
Implementacja protokołu ma kodeki zarówno dla C ++, jak i Java, co ciekawe, może zachować reprezentację klasy obiektów w postaci par nazwa-wartość, potrzebowałem podobnego protokołu w moim ostatnim projekcie, kiedy przypadkowo natknąłem się na ten protokół, faktycznie zmodyfikował bibliotekę bazową zgodnie z moimi wymaganiami. Mam nadzieję, że to ci pomoże.
źródło
Zalecam użycie serializacji boost, jak opisano w innych plakatach. Oto dobry szczegółowy samouczek, jak go używać, który dobrze uzupełnia samouczki dotyczące ulepszania: http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-serialization/
źródło
Sweet Persist to kolejna.
Możliwe jest serializowanie do i ze strumieni w formatach XML, JSON, Lua i binarnych.
źródło
Proponuję zajrzeć do fabryk abstrakcyjnych, które są często używane jako podstawa do serializacji
Odpowiedziałem w innym pytaniu SO dotyczącym fabryk C ++. Proszę, zobacz tam czy interesuje Cię elastyczna fabryka. Próbuję opisać stary sposób z ET ++ do używania makr, który świetnie się sprawdził.
ET ++ był projektem przeniesienia starego MacApp na C ++ i X11. W tym celu Eric Gamma itp. Zaczął myśleć o wzorcach projektowych . ET ++ zawierał automatyczne sposoby serializacji i introspekcji w czasie wykonywania.
źródło
Jeśli chcesz mieć prostą i najlepszą wydajność i nie zależy Ci na wstecznej kompatybilności danych, wypróbuj HPS , jest lekki, znacznie szybszy niż Boost itp. I znacznie łatwiejszy w użyciu niż Protobuf itp.
Przykład:
źródło
Oto prosta biblioteka serializatorów, którą podniosłem. To tylko nagłówek, c11 i ma przykłady serializacji podstawowych typów. Oto jeden z mapą do klasy.
https://github.com/goblinhack/simple-c-plus-plus-serializer
Wynik:
źródło
Do implementacji serializacji używam następującego szablonu:
Oto
T
typ, który chcesz serializować,Mode
jest typem fikcyjnym do rozróżniania różnych rodzajów serializacji, np. ta sama liczba całkowita może być serializowana jako little endian, big endian, varint itp.Domyślnie
Serializer
deleguje zadanie do serializowanego obiektu. W przypadku typów wbudowanych należy utworzyć specjalizację szablonuSerializer
.Dostępne są również wygodne szablony funkcji.
Na przykład serializacja little endian liczb całkowitych bez znaku:
Następnie do serializacji:
Aby deserializować:
Ze względu na abstrakcyjną logikę iteratora powinien działać z dowolnym iteratorem (np. Iteratorami strumienia), wskaźnikiem itp.
źródło