Deserializing constructor doesn#39;t read data correctly(反序列化构造函数无法正确读取数据)
问题描述
我正在尝试反序列化一个没有默认构造函数的对象.我已经看到您可以通过将存档传递给构造函数来做到这一点.但是,当我这样做时,它似乎没有正确读取数据?这是一个示例 - Works() 输出1 2",因为它应该(使用默认构造函数和运算符>>),但 DoesntWork() 输出0 0".我已经通过了,一切似乎都得到了适当的调用.谁能解释一下这两个函数的区别?
I am trying to deserialize an object that does not have a default constructor. I've seen that you can do this by passing an archive to a constructor. However, when I do this it does not seem to read the data correctly? Here is an example - Works() outputs "1 2" as it should (using a default constructor and the operator>>), but DoesntWork() outputs "0 0". I've stepped through and everything seems to be getting called appropriately. Can anyone explain the difference between these two functions?
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/serialization.hpp>
class Point
{
private:
    friend class boost::serialization::access;
    template<class TArchive>
    void serialize(TArchive& archive, const unsigned int version)
    {
        archive & mX;
        archive & mY;
    }
public:
    template<class TArchive>
    Point(TArchive& archive)
    {
        serialize(archive, 0);
    }
    Point(){} // Only provided to test Works()
    Point(const float x, const float y) : mX(x), mY(y) { }
    float mX = 4;
    float mY = 5;
};
void Works()
{
    std::cout << "Works():" << std::endl;
    Point p(1,2);
    std::ofstream outputStream("test.archive");
    boost::archive::text_oarchive outputArchive(outputStream);
    outputArchive << p;
    outputStream.close();
    // read from a text archive
    std::ifstream inputStream("test.archive");
    boost::archive::text_iarchive inputArchive(inputStream);
    Point pointRead;
    inputArchive >> pointRead;
    std::cout << pointRead.mX << " " << pointRead.mY << std::endl;
}
void DoesntWork()
{
    std::cout << "DoesntWork():" << std::endl;
    Point p(1,2);
    std::ofstream outputStream("test.archive");
    boost::archive::text_oarchive outputArchive(outputStream);
    outputArchive << p;
    outputStream.close();
    std::ifstream inputStream("test.archive");
    boost::archive::text_iarchive inputArchive(inputStream);
    Point pointRead(inputArchive);
    std::cout << pointRead.mX << " " << pointRead.mY << std::endl;
}
int main()
{
    Works(); // Output "1 2"
    DoesntWork(); // Output "0 0"
    return 0;
}
推荐答案
你不应该直接调用 serialize 方法:operator >> for a archive do way 不仅仅是调用 serialize;根据存档的类型,它首先需要加载前导码等.您可以通过调试器逐步执行或检查 test.archive 中的内容来验证这一点,就像
You shouldn't call serialize methods directly: operator >> for an archive does way more than just calling serialize; depending on the type of archive it first needs to load a preamble etc. You can verify this by stepping through with the debugger, or by checking what's inside test.archive, it is something like
22 serialization::archive 12 0 0 1.000000000e+000 2.000000000e+000
所以在构造一个 text_iarchive 之后,对 operator & 的前两次调用会碰巧看到那些 2 0 在那里实际数据.
so right after constructing a text_iarchive the first two calls to operator & will happen to see those 2 0's in there instead of the actual data.
你的构造函数应该是:
template<class TArchive>
Point(TArchive& archive)
{
  archive >> *this;
}
编辑这里是如何使用 SFINAE 确保仍然可以调用复制构造函数的示例
Edit here's an example of how to use SFINAE to make sure the copy constructor can still be invoked
Point( const Point& rh ) :
  mX( rh.mX ),
  mY( rh.mY )
{
}
template<class TArchive>
Point( TArchive& archive,
       std::enable_if_t< !std::is_same< TArchive, Point >::value >* = nullptr )
{
  archive >> *this;
}
                        这篇关于反序列化构造函数无法正确读取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:反序列化构造函数无法正确读取数据
				
        
 
            
        - 近似搜索的工作原理 2021-01-01
 - 静态初始化顺序失败 2022-01-01
 - 与 int by int 相比,为什么执行 float by float 矩阵乘法更快? 2021-01-01
 - C++ 协变模板 2021-01-01
 - 使用/clr 时出现 LNK2022 错误 2022-01-01
 - 从python回调到c++的选项 2022-11-16
 - 如何对自定义类的向量使用std::find()? 2022-11-07
 - Stroustrup 的 Simple_window.h 2022-01-01
 - STL 中有 dereference_iterator 吗? 2022-01-01
 - 一起使用 MPI 和 OpenCV 时出现分段错误 2022-01-01
 
						
						
						
						
						
				
				
				
				