反序列化构造函数不正确读取数据 [英] Deserializing constructor doesn't read data correctly
问题描述
我试图反序列化对象没有默认构造函数。我已经看到了你可以通过归档到一个构造函数做到这一点。但是,当我做到这似乎不正确读取数据?下面是一个例子 - 作品()
输出1 2,因为它应该(使用默认的构造和操作>>),但 DoesntWork( )
输出0。我踩通过,一切似乎变得适当调用。谁能解释这两个函数的区别?
的#include<&的fstream GT;#包括LT&;升压/存档/ text_oarchive.hpp>
#包括LT&;升压/存档/ text_iarchive.hpp>
#包括LT&;升压/系列化/ serialization.hpp>类Point
{
私人的:
友元类的boost ::系列化::访问; 模板<类TArchive>
无效连载(TArchive&安培;归档,const的无符号整型版)
{
归档和放大器; MX;
归档和放大器;我的;
}上市:
模板<类TArchive>
点(TArchive&安培;存档)
{
序列化(存档,0);
} 点(){} //仅提供给测试厂() 点(const的浮点X,常量浮动Y):MX(X),我(Y){} 浮MX = 4;
浮动我= 5;
};无效作品()
{
性病::法院LT&;< 工程():<<的std :: ENDL;
点p(1,2); 的std ::的ofstream的OutputStream(test.archive);
提高::档案:: text_oarchive的outputArchive(OutputStream中);
outputArchive<<磷;
outputStream.close(); //从文本阅读存档
性病:: ifstream的InputStream的(test.archive);
提高::档案:: text_iarchive inputArchive(InputStream的);
点pointRead;
inputArchive>> pointRead; 性病::法院LT&;< pointRead.mX<< << pointRead.mY<<的std :: ENDL;
}无效DoesntWork()
{
性病::法院LT&;< DoesntWork():&所述;&下;的std :: ENDL;
点p(1,2); 的std ::的ofstream的OutputStream(test.archive);
提高::档案:: text_oarchive的outputArchive(OutputStream中);
outputArchive<<磷;
outputStream.close(); 性病:: ifstream的InputStream的(test.archive);
提高::档案:: text_iarchive inputArchive(InputStream的);
点pointRead(inputArchive); 性病::法院LT&;< pointRead.mX<< << pointRead.mY<<的std :: ENDL;
}诠释的main()
{
作品(); //输出1 2
DoesntWork(); //输出0
返回0;
}
您应该不叫连载
方法直接:运营商的GT;>
的存档做的办法的不仅仅是打电话连载更多
;根据档案的种类它首先需要,或检查里面有什么test.archive加载preamble等,您可以通过使用调试器逐句通过验证这一点,它是一样的东西。
22 ::系列化存档12 0 0 1.000000000e + 000 2.000000000e + 000
所以构造之后立即 text_iarchive
前两个电话给运营商和放大器;
将碰巧看到那些2 0
的在那里,而不是实际的数据。
您的构造应该是:
模板<类TArchive>
点(TArchive&安培;存档)
{
归档>> *这个;
}
修改这里是如何使用SFINAE以确保拷贝构造函数仍然可以调用一个例子
点(常量点和放大器; RH):
MX(rh.mX)
我(rh.mY)
{
}模板<类TArchive>
点(TArchive&安培;存档,
的std :: enable_if_t< !的std :: is_same< TArchive,点> ::值> * = nullptr)
{
归档>> *这个;
}
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;
}
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
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.
Your constructor should be:
template<class TArchive>
Point(TArchive& archive)
{
archive >> *this;
}
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;
}
这篇关于反序列化构造函数不正确读取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!