Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在没有公共基类的情况下实现序列化_C++_Serialization_Boost_Boost Geometry - Fatal编程技术网

C++ 在没有公共基类的情况下实现序列化

C++ 在没有公共基类的情况下实现序列化,c++,serialization,boost,boost-geometry,C++,Serialization,Boost,Boost Geometry,我正在为以下问题寻求一些设计建议: 我使用的是boost geometry,我有几个与boost geometry兼容的自定义几何类型(通过traits),但我使用的大多数类型都是typedef class MyPoint { // custom stuff }; // declare traits for MyPoint for use wih boost geometry here class MyTaggedPoint : public MyPoint { // more cus

我正在为以下问题寻求一些设计建议:

我使用的是boost geometry,我有几个与boost geometry兼容的自定义几何类型(通过traits),但我使用的大多数类型都是typedef

class MyPoint
{
  // custom stuff
};
// declare traits for MyPoint for use wih boost geometry here

class MyTaggedPoint : public MyPoint
{
  // more custom stuff
};
// declare traits for MyTaggedPoint for use wih boost geometry here

// example typedefs
typedef boost::geometry::model::polygon<MyPoint>        Polygon;
typedef boost::geometry::model::polygon<MyTaggedPoint>  TaggedPolygon;
类MyPoint
{
//定制物品
};
//在此处声明MyPoint的特性,以便与boost几何体一起使用
类MyTaggedPoint:公共MyPoint
{
//更多定制的东西
};
//声明MyTaggedPoint的特性,以便在此处与boost几何体一起使用
//示例typedefs
typedef boost::geometry::model::polygon;
typedef boost::geometry::model::polygon标记多边形;
我的问题是何时要序列化/反序列化几何图形

假设所有几何图形都存储在数据库的二进制字段中。如果我有一个基本的几何类,我可能只需要编写g->type()(4字节)并调用g->save(some_outputstream)并将所有这些写入二进制字段。然后在读取二进制字段时,我只需读取字节并转换为适当的几何体类型

但是推进几何体没有通用的基类

当有多个类型可以存储为二进制且没有共享基类时,你们通常如何实现序列化?

我在考虑可能有一个序列化程序类,它会返回一个提升。然后可以使用(反)序列化程序中存储的类型对几何体进行强制转换?但是序列化程序需要为每种几何体类型使用一个save方法?例如:保存(myPolygon),保存(myPoint)


有什么想法/经验吗?

如果您不希望重新实现控制盘,则支持非侵入式序列化。您甚至可以在某个地方找到对其几何图形类型的库支持。不幸的是,由于XML方面的考虑,接口有点复杂。

要将对象序列化到字节和从字节序列化对象,对于必须支持的每种类型(灵长类、对象等),最终需要两个函数。它们是“Load()”和“Store()”

理想情况下,您可以为字节使用一个固定的接口—iostream、char*、一些缓冲区对象—等等。 为了可读性,让我们称之为“ByteBuffer”,因为从逻辑上讲,这就是它的作用

我们现在有一些类似于可序列化概念的模板函数:

template<typename T>
ByteBuffer Store(const T& object) { // BUT, What goes here...? }

template<typename T>
T Load(const ByteBuffer& bytes);
为了检查错误,我们可以在派生构造函数可以设置的基类中提供一个受保护的标志“valid”。请注意,您的对象必须支持工厂样式的构造,Load()才能很好地使用它

现在我们可以这样做了,作为工厂提供“负载”:

template<typename T>
class Serializable // If you do reference-counting on files & such, you can add it here
{
protected:
    bool valid;

    // Require derived to mark as valid upon load
    Serializable() : valid(false) {}
    virtual ~Serializable() { valid = false; }

public:
    static T Load(const ByteBuffer& bytes); // calls a "T(bytes)" constructor

    // Store API
    virtual ByteBuffer Store() = 0;  // Interface details are up to you.
};
模板
类Serializable//如果您对文件进行引用计数,那么可以将其添加到此处
{
受保护的:
布尔有效;
//要求在加载时将派生标记为有效
Serializable():有效(假){}
virtual~Serializable(){valid=false;}
公众:
静态T加载(constbytebuffer&bytes);//调用“T(bytes)”构造函数
//存储API
virtual ByteBuffer Store()=0;//接口详细信息由您决定。
};
现在,只需像这样从基类派生,就可以获取所需的一切:

class MyObject : public Serializable<MyObject>
{
protected:
   // .. some members ...

   MyObject(const ByteBuffer& bytes)
   {
      //... Actual load logic for this object type ...
      // On success only:
      valid = true;
   }

public:
   virtual ByteBuffer Store() {
      //... store logic 
   }
};
类MyObject:可公共序列化
{
受保护的:
//……一些成员。。。
MyObject(常量字节缓冲和字节)
{
//…此对象类型的实际加载逻辑。。。
//仅就成功而言:
有效=真;
}
公众:
虚拟ByteBuffer存储(){
//…存储逻辑
}
};
最酷的是,您可以调用“MyObject::Load()”,它将完全按照您的期望执行。此外,“加载”可以成为构建对象的唯一方式,允许您为只读文件等清理API

将其扩展到完整文件API需要更多的工作,即添加一个可以从更大的缓冲区(保存其他内容)读取的“Load()”和附加到现有缓冲区的“Store()”


请注意,不要为此使用boost的API。在一个好的设计中,可序列化对象应该1对1映射到磁盘上原始类型的压缩结构——这是生成的文件真正可供其他程序或其他机器使用的唯一方法。Boost为您提供了一个可怕的API,它主要使您能够做一些您以后会后悔的事情。

+1用于Boost.Serialization,尤其是因为他已经在使用Boost。
class MyObject : public Serializable<MyObject>
{
protected:
   // .. some members ...

   MyObject(const ByteBuffer& bytes)
   {
      //... Actual load logic for this object type ...
      // On success only:
      valid = true;
   }

public:
   virtual ByteBuffer Store() {
      //... store logic 
   }
};