1. 程式人生 > >boost vs2015 序列化 動態物件

boost vs2015 序列化 動態物件

問題 : 需要將 list<person *> 序列化並儲存到xml中,再將xml讀取並得到 list<person *>,其中person是基類; 有其他的類作為其子類:developer和developer2等。

 

  1. 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.htmlhttps://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