我有点不舒服。为了从内存中保存/加载指针,我使用了boost::序列化。拯救的部分,我没有问题。我能够验证序列化类是否能够在没有任何问题的情况下保存指针。另外,指针类是我创建的自定义类。
一些背景。我正在使用wxwidget库创建一个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中的序列化函数中放置了一个断点,而程序从未做到这一点。
我确实看到了这个论坛的帖子: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)票面一定有价值。空值不被接受。我确实看到了论坛帖子确实覆盖了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数据类型,并且无法保存此数据类型)?
是的,我知道最起码的例子。我需要一些时间来创建一个最小的例子。如果论坛的人们需要它来有效地想出一个解决方案,那么我会这样做并在这里发布。但同样,这将需要时间,可能会相当长。
发布于 2017-08-05 09:13:33
是的,加载/保存构造数据是处理非默认构造性的工具。
您的问题是不同的:您需要外部状态,因为您正在尝试加载在构造过程中需要状态的对象,但它从一开始就没有被保存。如果是的话,您就可以像序列化期间一样重新创建父窗口。
我在这里看到的唯一“解决办法”是使用全局状态(即通过(线程)全局变量访问它)。
我不建议你这样做,但你现在很麻烦,所以考虑一下解决办法,即使是不好的,也是件好事。
一旦您从旧式档案中提取数据,我建议将其序列化为以下格式:
当然,我不知道这里的首要目标,所以我不能说哪种方法更合适,但是没有上下文,我总是争相分离关注点,即将序列化与任何UI元素去耦合。
https://stackoverflow.com/questions/45512699
复制相似问题