boost vs2015 序列化 動態物件
問題 : 需要將 list<person *> 序列化並儲存到xml中,再將xml讀取並得到 list<person *>,其中person是基類; 有其他的類作為其子類:developer和developer2等。
-
class person { public: person() { } person(int age) : age_(age) { } virtual int age() const { return age_; } virtual int kk() = 0; pal pal1; int age_; private: friend class boost::serialization::access; template <typename Archive> void serialize(Archive &ar, const unsigned int version) { ar & age_; ar & pal1; } }; class developer : public person { public: developer() { } developer(int age, const std::string &language) : person(age), language_(language) { } std::string language() const { return language_; } virtual int kk() { return 11; } virtual int age() { return 199; } private: friend class boost::serialization::access; template <typename Archive> void serialize(Archive &ar, const unsigned int version) { ar & boost::serialization::base_object<person>(*this); ar & language_; } std::string language_; };
第一步 下載boost;
這個網上有許多,但是不編譯的就需要在官網上下載預編譯的版本,這個根據自己電腦的安裝環境選擇,
(編譯的版本很多,但是容易出問題,我使用命令列幾次都報錯,網上也沒人解答類似的問題,還很花時間, 這個https://blog.csdn.net/misterfm/article/details/79048594 看起來還不錯)
官網地址: https://www.boost.org/ (官網)和https://www.boost.org/users/download/(下載地址)
參考:https://blog.csdn.net/feierban/article/details/80283727
我下載的boost_1_68_0-msvc-14.0-32.exe ,14.0是指vs2015,32= 32位系統;
下好以後,執行得到:
其實lib32-msvc-14.0這個目錄就是編譯好的目錄(包含各種lib和dll);
開啟vs2015,在專案的屬性 vc++
接著連結器的附加庫目錄:編譯好的目錄
接著在程式碼中新增#include 就會發現有boost目錄
這就是vs2015新增比較快的方法,還有更快的,就是開啟 屬性-》管理nuget程式包,
查詢boost就行了,但是我的程式還是提示有錯,最後又載入了附加目錄庫(D:\local\boost_1_68_0\lib32-msvc-14.0)就好了。
第二步 boost 序列化;
參考 https://blog.csdn.net/wojiushiwoba/article/details/59527911;這個是大致瞭解概念;
具體實現參考:http://zh.highscore.de/cpp/boost/serialization.html和https://blog.csdn.net/zj510/article/details/8105408
1 boost serialization;標頭檔案
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
主要的轉化
#include <boost/serialization/export.hpp>
巨集
#include<boost\serialization\list.hpp>
物件中 list類的轉換
#include <iostream>
#include <sstream>
輸入輸出流
#include <string>
2 boost serialization 侵入式(非侵入式沒寫)
在類中加入
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
//類中需要序列化的;可以支援指標
ar & sss;
}
所有需要序列化的都要在serialize中,而且基類物件或成員物件中也需要實現serialize;
從上面可以看出,boost是使用text_oarchive和text_iarchive 類,來完成一個物件的序列化的。使用這兩個類的步驟是:
在源程式中包含boost/archive/text_oarchive.hpp 和 boost/archive/text_iarchive.hpp 這兩個檔案。
為需要序列化的類新增一個template<class Archive> void serialize(Archive & ar, const unsigned int version)的模版成員函式。 如果需要物件中包含私有成員的話,需要把boost::serialization::access類宣告為友元。
在主函式中,建立一個輸出檔案流物件, 使用這個物件構造一個text_oarchive物件,然後就可以使用<<操作符來輸出物件了。
最後,同樣的,使用text_iarchive來恢復物件。(xml 類似)
重點:在基類中需要是一個虛擬函式(可以讓boost知道是基類),這裡我將person的一個函式kk變為純虛擬函式,在develop中實現kk。子類需要定義BOOST_CLASS_EXPORT(developer)。
第三步測試
mian.cpp
#include "stdafx.h"
#include <iostream>
#include <string>
#include <string>
#include <sstream>
using namespace std;
void TestPointerArchive();
std::stringstream ss;
std::stringstream ss1;
void save1()
{
boost::archive::text_oarchive oa(ss);
boost::archive::text_oarchive oa2(ss1);
person *p = new developer(31, "C++");
person *p2 = new developer2(32, "C+2+");
oa << p<<p2;
oa2 << p2;
delete p2;
delete p;
}
void load1()
{
boost::archive::text_iarchive ia(ss);
boost::archive::text_iarchive ia2(ss1);
person *p;
person *p2;
person *p3;
ia >> p;
ia >> p3;
ia2 >> p2;
std::cout << p->kk() << std::endl;
std::cout << p3->kk() << std::endl;
std::cout << p2->kk() << std::endl;
delete p;
delete p2;
}
int main()
{
list<person *> listp;
list<person *> listp2;
boost::archive::text_oarchive oa(ss);
person *p = new developer(31, "C++");
person *p2 = new developer2(32, "C+2+");
test *tt = new test();
tt->sss = 99;
pal *pal2 = new pal();
pal2->bb = 111;
pal2->kk = 112;
pal2->test1 = tt->cloner();
pal *pal3 = pal2->cloner();
pal3->kk = 113;
p->pal1 = *pal2;
p2->pal1 = *pal3;
listp.push_back(p);
listp.push_back(p2);
oa << listp;
boost::archive::text_iarchive ia(ss);
ia >> listp2;
for each (person*p in listp2)
{
std::cout << p->kk()<<" "<<p->pal1.test1->sss << std::endl;
}
}
boost1.cpp
#pragma once
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/export.hpp>
#include<boost\serialization\list.hpp>
#include <iostream>
#include <sstream>
#include <string>
class test
{
public:
int sss;
test * cloner() {
test *t = new test();
*t = *this;
return t;
}
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & sss;
}
};
class pal {
public:
int kk;
int bb;
test *test1;
pal * cloner() {
pal *a = new pal();
*a = *this;
return a;
}
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & kk;
ar & bb;
ar &test1;
}
};
class person
{
public:
person()
{
}
person(int age)
: age_(age)
{
}
virtual int age() const
{
return age_;
}
virtual int kk() = 0;
pal pal1;
int age_;
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & age_;
ar & pal1;
}
};
class developer
: public person
{
public:
developer()
{
}
developer(int age, const std::string &language)
: person(age), language_(language)
{
}
std::string language() const
{
return language_;
}
virtual int kk() {
return 11;
}
virtual int age() {
return 199;
}
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<person>(*this);
ar & language_;
}
std::string language_;
};
class developer2
: public person
{
public:
developer2()
{
}
developer2(int age, const std::string &language)
: person(age), language_(language)
{
}
std::string language() const
{
return language_;
}
virtual int kk() {
return 12;
}
virtual int age() {
return 1992;
}
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<person>(*this);
ar & language_;
}
std::string language_;
};
BOOST_CLASS_EXPORT(developer)
BOOST_CLASS_EXPORT(developer2)
測試專案 github:https://github.com/gzj1997/boost-3