gpt4 book ai didi

c++ - 如何使用非默认构造函数的指针进行 Boost 序列化

转载 作者:搜寻专家 更新时间:2023-10-31 02:10:18 24 4
gpt4 key购买 nike

我有点难过。我正在使用 boost::serialization 来保存/加载内存中的指针。储蓄部分,我没有问题。我能够验证序列化类能够毫无问题地保存指针。附带说明一下,指针类是我创建的自定义类。

一些背景。我正在使用 wxwidgets 库创建一个 GUI。我使用的是最新版本 (v3.1.0)。该对象继承自 wxGLCanvas 类。这需要一个指向父窗口的指针。该类用于在屏幕上绘制网格,用户可以通过放置几何形状(主要是正方形、弧形和直线)与网格进行交互。每个形状都是它自己的类。在我的类(class)中,我有指定网格步长、相机位置、缩放级别和几何形状 vector 的数据类型。所有这些都可以保存。请注意,我的类(class)也确实指定了其他数据类型,但我没有保存这些数据类型,因此它们与讨论无关。作为旁注,有问题的类称为 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)

par 必须有一个值。不接受空值。我确实看到论坛帖子确实覆盖了加载函数并获取了值并将它们传递给类的构造函数。但是,在我的例子中,par 是一个 this 指针,我无法序列化函数并将 this 加载回程序(此外,this 将在每次函数调用时改变)。 this 指向父窗口。覆盖不同命名空间中的加载函数会阻止我将 this 传递到函数中。所以基本上,这个选项是不可能的(除非我遗漏了什么)。

同样,因为我不能将 NULL 传递给 wxGLCanvas 构造函数,所以这个选项不在考虑范围内:

modelDefinition _model = new modelDefinition();
modelDefinition::modelDefinition() : wxGLCanvas(NULL, 0)

而且我相信这个选项也不在讨论范围内,因为与 Canvas 关联的父窗口位于不同的命名空间中:

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 do not recommend it, but you're in a pickle so it's good to think about workarounds, even bad ones

一旦您从旧式存档中抢救了数据,我建议将其序列化为一种格式

  • 保存所有必需的构造数据
  • 序列化一个与 GUI 元素无关的数据结构

当然我不知道这里的总体目标,所以我不能说哪种方法更合适,但如果没有上下文,我总是会努力分离关注点,即将序列化与任何 UI 元素。

关于c++ - 如何使用非默认构造函数的指针进行 Boost 序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45512699/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com