在构造函数中反编译C ++中的对象

时间:2014-03-10 21:21:32

标签: c++ serialization deserialization

在C ++中使用重载构造函数反序列化对象是一个好习惯,或者最好创建一个成员函数deserialize(std :: istream& file)?

3 个答案:

答案 0 :(得分:5)

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

例如

class Foo
{
    Foo(int x)
    ...
}

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

可以创建一个成员函数,但我个人更喜欢将它与该类分开(尽管我经常把它放在同一个文件中),对我而言,这将破坏封装。 / p>

答案 1 :(得分:1)

在构造函数中放入反序列化可能会限制您处理失败案例的灵活性(例如,损坏的输入数据)。专用成员函数更灵活。例如,它允许您return状态值,而构造函数不能返回值来指示失败。是否需要以牺牲RAII为代价来实现这种灵活性取决于您。

答案 2 :(得分:1)

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

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);