我一直在努力解決我在使用boost :: serialization序列化一些數據時遇到的問題。boost :: serialization - 序列化從通用屬性/特徵容器派生的類
我試圖實現一個選項卡式編輯器,利用客戶端/服務器體系結構爲我正在進行的項目。目前的設計是這樣的:
DerivedTab從基標籤類擴展。 (對於這個示例問題,我選擇不包含DerivedTab類的示例。)。
標籤類擴展AttributeContainer類,其中包含地圖的字符串的屬性名稱AttributeBase *。
屬性是延伸AttributeBase一個模板類。它旨在用作通用數據類型,可以保存任何具體數據類型的值。
最後,AttributeBase從NetworkSerializable它是用作一個基礎對象類型,以確定可通過網絡連接被序列化的對象必須按照合同純抽象基類派生的。
所有這些都被編譯成一個庫,然後靜態鏈接到我的主應用程序。正如你所看到的那樣,有很多間接方向正在進行,並且我試圖用boost :: serialization序列化來解決一些問題。我已經刪除了所有與獲取這些類進行序列化無關的代碼。但是,示例代碼仍然很長。
main.cpp中:
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include "Tab.h"
using namespace test;
int main(int argc, char **argv)
{
std::ostringstream oarchiveStream;
boost::archive::text_oarchive outputArchive(oarchiveStream);
Tab* tab = new Tab("temp");
bool tempBool = true;
tab->RegisterAttribute("tempBool", "a temp boolean", &tempBool);
std::string tempString("1234");
tab->RegisterAttribute("tempString", "a temp string", &tempString);
outputArchive << tab;
}
Tab.h:
#ifndef __TAB_H__
#define __TAB_H__
#include "AttributeContainer.h"
#include <boost/serialization/base_object.hpp>
namespace test
{
class Tab : public AttributeContainer
{
friend class boost::serialization::access;
public:
Tab(const std::string tabName);
virtual ~Tab();
protected:
Tab();
template<class archive>
inline void serialize_attributes(archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(AttributeContainer);
ar & boost::serialization::make_nvp("TabName", _tabName);
}
virtual void serialize(boost::archive::text_oarchive& oa, const unsigned int version);
virtual void serialize(boost::archive::text_iarchive& ia, const unsigned int version);
private:
std::string _tabName;
};
} // namespace test
BOOST_CLASS_EXPORT_KEY(test::Tab);
#endif // #ifndef __TAB_H__
Tab.cpp:
#include "Tab.h"
BOOST_CLASS_EXPORT_IMPLEMENT(test::Tab);
using namespace test;
Tab::Tab(const std::string tabName) : _tabName(tabName)
{
}
Tab::~Tab()
{
}
Tab::Tab() : _tabName("")
{
}
void Tab::serialize(boost::archive::text_oarchive& oa, const unsigned int version)
{
std::cout << "Tab::serialize" << std::endl;
serialize_attributes(oa, version);
}
void Tab::serialize(boost::archive::text_iarchive& ia, const unsigned int version)
{
serialize_attributes(ia, version);
}
AttributeContainer.h:
#ifndef __ATTRIBUTE_CONTAINER_H__
#define __ATTRIBUTE_CONTAINER_H__
#include "NetworkSerializable.h"
#include <boost/serialization/map.hpp>
#include "Attribute.h"
namespace test
{
class AttributeContainer : public NetworkSerializable
{
friend class boost::serialization::access;
public:
std::map<std::string, AttributeBase*> _attributes;
AttributeContainer() {};
virtual ~AttributeContainer() {};
template <typename _T>
void RegisterAttribute(const std::string& name, const std::string& description, _T* var)
{
std::map<std::string, AttributeBase*>::const_iterator pos;
if ((pos = _attributes.find(name)) == _attributes.end())
{
Attribute<_T>* attribute = new Attribute<_T>(name, description, var);
_attributes.insert(std::map<std::string, AttributeBase*>::value_type(name, attribute));
}
};
template <class archive>
inline void serialize_attributes(archive& ar, const unsigned int version)
{
ar & _attributes;
};
virtual void serialize(boost::archive::text_oarchive& oa, const unsigned int version);
virtual void serialize(boost::archive::text_iarchive& ia, const unsigned int version);
}; // end class AtributeContainer
} // end namespace test
BOOST_CLASS_EXPORT_KEY(test::AttributeContainer);
#endif // #ifndef __ATTRIBUTE_CONTAINER_H__
AttributeContainer.cpp:
#include "AttributeContainer.h"
BOOST_CLASS_EXPORT_IMPLEMENT(test::AttributeContainer);
using namespace test;
void AttributeContainer::serialize(boost::archive::text_oarchive& oa, const unsigned int version)
{
std::cout << "AttributeContainer::serialize" << std::endl;
serialize_attributes(oa, version);
}
void AttributeContainer::serialize(boost::archive::text_iarchive& ia, const unsigned int version)
{
serialize_attributes(ia, version);
}
Attribute.h:
#ifndef __ATTRIBUTE_H__
#define __ATTRIBUTE_H__
#include "AttributeBase.h"
namespace test
{
template <typename _T>
class Attribute : public AttributeBase
{
friend class AttributeContainer;
friend class boost::serialization::access;
public:
typedef _T AttributeType;
Attribute() : _data(0) {}
Attribute(const std::string& name, const std::string& description, AttributeType* var) : _data(var)
{
_name = name;
_description = description;
}
virtual ~Attribute() {}
protected:
AttributeType* _data;
template <class archive>
inline void serialize_base(archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(AttributeBase);
ar & boost::serialization::make_nvp("Value", *_data);
}
virtual void serialize(boost::archive::text_oarchive& oa, const unsigned int version)
{
std::cout << "Attribute::serialize" << std::endl;
serialize_base(oa, version);
}
virtual void serialize(boost::archive::text_iarchive& ia, const unsigned int version)
{
serialize_base(ia, version);
}
};
} // namespace test
BOOST_CLASS_EXPORT_KEY(test::Attribute<bool>);
BOOST_CLASS_EXPORT_KEY(test::Attribute<std::string>);
#endif // #ifndef __ATRIBUTE_H__
Attribute.cpp:
#include "Attribute.h"
BOOST_CLASS_EXPORT_IMPLEMENT(test::Attribute<bool>);
BOOST_CLASS_EXPORT_IMPLEMENT(test::Attribute<std::string>);
using namespace test;
AttributeBase.h:
#ifndef __ATTRIBUTE_BASE_H__
#define __ATTRIBUTE_BASE_H__
#include "NetworkSerializable.h"
#include <string>
namespace test
{
class AttributeBase : public NetworkSerializable
{
friend class AttributeContainer;
friend class boost::serialization::access;
public:
AttributeBase();
virtual ~AttributeBase();
protected:
AttributeBase& operator=(const AttributeBase&);
AttributeBase(const AttributeBase&);
protected:
std::string _name;
std::string _description;
template<class archive>
inline void serialize_attributes(archive& ar, const unsigned int version)
{
ar & boost::serialization::make_nvp("Name", _name);
ar & boost::serialization::make_nvp("Description", _description);
}
virtual void serialize(boost::archive::text_oarchive& oa, const unsigned int version);
virtual void serialize(boost::archive::text_iarchive& ia, const unsigned int version);
}; // end class AttributeBase
} // end namespace test
BOOST_SERIALIZATION_ASSUME_ABSTRACT(test::AttributeBase);
BOOST_CLASS_EXPORT_KEY(test::AttributeBase);
#endif // #ifndef __ATTRIBUTE_BASE_H__
NetworkSerializable。H:
#ifndef __NETWORK_SERIALIZABLE_H__
#define __NETWORK_SERIALIZABLE_H__
#pragma warning(disable:4244)
#include <boost/shared_ptr.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
namespace test
{
class NetworkSerializable
{
friend class boost::serialization::access;
public:
typedef std::shared_ptr<NetworkSerializable> NetworkSerializablePtr;
NetworkSerializable() {};
protected:
virtual void serialize(boost::archive::text_oarchive& oa, const unsigned int version) = 0;
virtual void serialize(boost::archive::text_iarchive& ia, const unsigned int version) = 0;
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(NetworkSerializable);
} // namespace test
#endif // #ifndef __NETWORK_SERIALIZABLE_H__
我試圖使代碼簡潔和最小的儘可能充分展示我遇到的問題。
從所提供的代碼的輸出是:
Tab::serialize
Tab::serialize
當輸出應該是:
Tab::serialize
AttributeContainer::serialize
Attribute::serialize
AttributeBase::serialize
Attribute::serialize
AttributeBase::serialize
有相當多的代碼在這裏的人消化,所以我會很感激如果任何人都可以提供任何我可能沿着boost序列化路徑偏離的見解。
可能重複[?如何序列化派生模板類與Boost.serialize(http://stackoverflow.com/questions/1332602/how-to-serialize-derived-template-classes-with-boost-serialize) –
下次,請繼續關注你的例子。在減少到SSCCE時,你不僅可能冒險自己發現問題,而且你也不需要隨機的陌生人來處理代碼。 – sehe