假设我们有一个复杂的(即非原始的)类 ComplexObject
定义如下:
class A{...};
class B{...};
class C{...};
class ComplexObject
{
private:
A _fieldA;
B _fieldB;
C _fieldC;
};
我想实现一个序列化程序,将 ComplexObject
的实例序列化为二进制形式。根据我在 C# 方面的经验,我基本上看到了 3 种不同的方式来实现序列化程序。
- 在
ComplexObject
和“子”类的定义中定义一个serialize(binarystream&)
方法,A
,B
和C
。ComplexObject
中定义的serialize
方法将递归调用那些子成员。 - 创建一个单独的类,其中包含序列化每个
ComplexObject
、A
、B
和C
的方法.用于序列化ComplexObject
的方法将递归调用子成员的方法。当然,必须在类中定义 getter 以检索序列化程序的私有(private)字段。 - 使用反射生成对象的模板,并根据生成的模板将所有可序列化的字段写入表中。
不幸的是,我认为反射在 C++ 中使用起来非常困难,所以我将远离第三种选择。我看到选项 1 和 2 都被经常使用(在 C# 中)。
选项 1 优于选项 2 的一个优势是它允许从 ComplexObject
派生的类,方法是将 serilalize(binarystream&)
方法标记为虚拟。但是,它会添加到对象的成员函数列表中并使程序员感到困惑。您没有看到 std::string
中定义了 serialize
方法,是吗?
另一方面,选项 2 删除所有序列化方法并将其组合在一起,使事情变得更整洁。但是,我认为适应 ComplexObject
的派生类并不容易。
在什么情况下应使用每个选项(1 和 2)?
最佳答案
我选择“两者”。序列化在对象和(模板化的)独立函数中有组件。
例如:
class Serialization_Interface
{
public:
virtual void load_from_buffer(uint8_t*& buffer_ptr) = 0;
};
void Load_From_Buffer(unsigned int& number, uint8_t*& buffer_pointer)
{
number = *((unsigned int *) buffer_ptr);
buffer_pointer += sizeof(unsigned int);
}
template <class Object>
void Load_From_Buffer(Object& obj, uint8_t*& buffer_pointer)
{
obj.load_from_buffer(buffer_pointer);
}
不要将自己局限于两种选择。总有第三种选择。 :-)
此外,不要重新发明轮子,查看 Boost::serialization。
关于c++ - C/C++ : Should serialization methods be class members?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25836251/