【发布时间】:2018-01-12 17:46:13
【问题描述】:
我有点吃不消了。我正在使用 boost::serialization 来保存/加载内存中的指针。节省部分,我没有问题。我能够验证序列化类能够毫无问题地保存指针。附带说明一下,指针类是我创建的自定义类。
一些背景。我正在使用 wxwidgets 库来创建 GUI。我正在使用最新版本(v3.1.0)。该对象继承自 wxGLCanvas 类。这需要一个指向父窗口的指针。该类用于在屏幕上绘制网格,用户可以通过放置几何形状(主要是正方形、弧线和线条)与网格进行交互。每个形状都是它自己的类。在我的班级中,我有一些数据类型来指定网格步长、相机的位置、缩放级别和几何形状矢量。所有这些都可以被保存。请注意,我的课程也指定了其他数据类型,但我没有保存这些数据类型,因此它们与讨论无关。附带说明一下,有问题的类称为 modelDefinition
现在,我们来到类的加载部分。我目前的实现是这样的:
void MainFrame::load(string filePath)
{
std::ifstream loadFile(filePath);
if(loadFile.is_open())
{
modelDefinition temp(this, wxPoint(6, 6), this->GetClientSize(), _problemDefinition, this->GetStatusBar());
//modelDefinition tempDefintion = (*_model);
boost::archive::text_iarchive ia(loadFile);
ia >> _problemDefinition;
ia >> temp;
temp.copyModel(*_model);
//*_model = temp;
//(*_model) = tempDefintion;
_model->Refresh();
}
}
复制功能的实现:
void copyModel(modelDefinition &target)
{
target.setGridPreferences(_preferences);
target.setEditor(_editor);
target.setZoomX(_zoomX);
target.setZoomY(_zoomY);
target.setCameraX(_cameraX);
target.setCameraY(_cameraY);
}
我的想法是,我创建一个临时变量并将其初始化为我需要的值。目前,它是空的。然后,我将数据加载到临时变量中,然后将所需的数据结构复制到我的主变量中。但是,程序在ia >> temp 处崩溃。我现在不知道为什么。我进入调试器,崩溃后无法访问调用堆栈。我有一种感觉,它在 boost 库中崩溃了。我确实在 modelDefinition 的 serialize 函数中放置了一个断点,但程序从未成功。
我确实遇到过这个论坛帖子: Boost serialization with pointers and non-default constructor
说实话,我不太确定它是否适用于我。我正在尝试一种方法,但到目前为止我找不到任何适用于我的理由。
这里是modelDefinition构造函数的声明:
modelDefinition::modelDefinition(wxWindow *par, const wxPoint &point, const wxSize &size, problemDefinition &definition, wxStatusBarBase *statusBar) : wxGLCanvas(par, wxID_ANY, NULL, point, size, wxBORDER_DOUBLE | wxBORDER_RAISED)
par 必须有一个值。不接受空值。我确实看到论坛帖子确实覆盖了加载函数并获取了值并将它们传递给类的构造函数。然而,在我的例子中,par 是一个this 指针,我无法序列化函数并将this 加载回程序中(此外,this 将在每个函数调用时更改)。 this 指回父窗口。并且在不同的命名空间中覆盖加载函数会阻止我将 this 传递给函数。因此,基本上,该选项不可行(除非我遗漏了什么)。
再次,由于我无法将 NULL 传递给 wxGLCanvas 构造函数,因此该选项不可用:
modelDefinition _model = new modelDefinition();
modelDefinition::modelDefinition() : wxGLCanvas(NULL, 0)
而且我相信这个选项也不在讨论范围内,因为与画布关联的父窗口位于不同的命名空间中:
template<class Archive>
inline void load_construct_data(
Archive & ar, modelDefintion * foo, const unsigned int file_version
){
double test;// There would be more after this but to simplify the posting, I am just throwing this in here.
ar >> test;
::new(modelDefintion)_model(this, test); // Yeah, I don't think that this is going to work here.
}
同样,this 需要指向父窗口,我认为我无法访问。
所以现在,我对自己的选择有点迷茫。到目前为止,我认为我将继续研究第一个案例,看看程序在哪里崩溃。
虽然,我真的可以借助某人的帮助来解决这个问题。在无法保存继承对象的数据(因为 modelDefinition 继承自 wxGLCanvas 数据类型并且我无法保存此数据类型)的情况下,如何加载非默认构造函数指针的数据结构?
是的,我知道最小的例子。我需要一些时间来创建一个最小的例子。如果论坛人们需要它来有效地提出解决方案,那么我会这样做并在这里发布。但同样,这需要时间,而且可能会相当长。
【问题讨论】:
-
I go into the debugger and I do not get access to the call stack after the crash.这太奇怪了。您运行的是调试版还是优化版? -
@SergeyA 是的,没错。有趣的是,我正在优化它以进行调试。我仍在检查设置以确保我没有错过任何东西。当我在终端中运行程序时,它崩溃并产生了这个错误输出:
*** Caught unhandled std::exception of type "N5boost7archive17archive_exceptionE", what() = "input stream error"; terminating
标签: c++ pointers serialization boost