构造函数中C++中对象的反序列化



在C++中使用重载构造函数反序列化对象是一种很好的做法,还是最好创建一个成员函数反序列化(std::istream&file(?

我建议创建一个单独的deserializer函数,因为它分离了责任(即构造函数不需要担心如何获取信息(。

例如

class Foo
{
    Foo(int x)
    ...
}
Foo FooDeserialiser(Data data)
{
    // get data to pass to constructor
    return Foo(someInt);
}

可以创建一个成员函数,但我个人更喜欢将其与类分离(尽管我经常将其放在同一个文件中(,因为对我来说,这会破坏封装。

是的。您可以避免两步初始化以及由此引发的所有问题。有些opject"未初始化"的存在是没有意义的。因此,至少在这种情况下,您应该将序列化代码放入构造函数中。这种设计的优点是,您可以使用相同的构造函数进行读写。并且不能违反初始化基类或成员类的顺序。唯一的缺点是,在编写时,您会临时创建要写入的对象的副本。如果这是一个问题,您仍然可以将构造函数代码复制到某个编写方法中。当然,你应该是本世纪的一部分,在阅读和写作时对错误使用异常处理。你真的想让CReadWrite类可以从一些抽象的CRead和CWrite中构造出来,这样你就可以从"某处"读写,包括文件、管道、套接字、内存缓冲区,谁知道你的客户后天会出现什么。

struct CReadWrite;
struct A:B
{   std::string m_sName; 
    A(const A *const pWrite, CReadWrite *const pFile)
        :B(pWrite ? static_cast<B*>(pWrite) : 0, pFile),
        m_sName(pFile->readWrite(pWrite ? &pWrite->m_sName : 0))
    {
    }
};

读取:

CReadWrite sFile("test.dat", "r");
A sA(0, &sFile);

写入:

CReadWrite sFile("test.dat", "w");
A sA;
A(&sA, &sFile);

在构造函数中进行反序列化可能会限制您处理失败情况(例如,损坏的输入数据(的灵活性。专门的成员功能更灵活。例如,它允许return一个状态值,而构造函数不能返回一个表示失败的值。您是否需要以失去RAII为代价的这种灵活性取决于您。

相关内容

  • 没有找到相关文章

最新更新