我有点腌渍。我正在使用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必须有一个值。不接受空值。我确实看到论坛帖子覆盖了load函数并抓取了值并将它们传递给了类的构造函数。但是,在我的情况下,par是一个this
指针,我无法序列化该函数并将this
加载回程序(此外,this
将在每个函数调用时更改)。 this
引用父窗口。并且在不同的命名空间中覆盖load函数会阻止我将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数据类型,我无法保存此数据类型)?
是的,我知道最小的例子。创建一个最小的例子需要一些时间。如果论坛人员需要它来有效地提出解决方案,那么我会在这里发布并发布。但同样,这需要时间,而且可能会很长。
答案 0 :(得分:2)
是的,加载/保存构造数据是处理非默认构造的工具。
你的问题是不同的:你需要从外面的状态,因为你正在尝试加载在施工期间需要状态的对象,但它从来没有被保存过。如果是这样,您可以像在序列化过程中存在的那样重新创建父窗口。
我在这里可以看到的唯一“解决方法”是使用全局状态(即通过(线程)全局变量访问它)。
我不推荐它,但你是一个泡菜,所以考虑解决方法很好,甚至是坏的
一旦您从旧式档案中挽救了数据,我建议您序列化为
格式当然我不知道这里的主要目标,所以我不能说哪种方法更贴切,但是没有上下文我总是争先恐后地分离关注点,即将序列化与任何UI元素。