首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用带有非默认构造函数的指针处理Boost序列化

如何使用带有非默认构造函数的指针处理Boost序列化
EN

Stack Overflow用户
提问于 2017-08-04 17:44:20
回答 1查看 276关注 0票数 2

我有点不舒服。为了从内存中保存/加载指针,我使用了boost::序列化。拯救的部分,我没有问题。我能够验证序列化类是否能够在没有任何问题的情况下保存指针。另外,指针类是我创建的自定义类。

一些背景。我正在使用wxwidget库创建一个GUI。我正在使用最新版本(v3.1.0)。对象继承自wxGLCanvas类。它需要指向父窗口的指针。这个类用于在屏幕上绘制网格,用户可以通过放置几何图形(主要是正方形、弧形和线条)与网格交互。每个形状都是自己的类。在我的类中,我有指定网格步长、相机位置、缩放级别和几何形状向量的数据类型。所有这些都能被拯救。请注意,我的类也指定了其他数据类型,但我没有保存这些类型,因此它们与讨论无关。顺便提一下,这个类被称为modelDefinition。

现在,我们讨论类的加载部分。我目前的实现如下:

代码语言:javascript
复制
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();
    }
}

副本功能的实现:

代码语言:javascript
复制
    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构造函数的声明操作:

代码语言:javascript
复制
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构造函数,因此该选项不在表中:

代码语言:javascript
复制
modelDefinition _model = new modelDefinition();
modelDefinition::modelDefinition() : wxGLCanvas(NULL, 0)

我认为这个选项也不在表中,因为与画布相关联的父窗口位于不同的名称空间中:

代码语言:javascript
复制
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数据类型,并且无法保存此数据类型)?

是的,我知道最起码的例子。我需要一些时间来创建一个最小的例子。如果论坛的人们需要它来有效地想出一个解决方案,那么我会这样做并在这里发布。但同样,这将需要时间,可能会相当长。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-05 09:13:33

是的,加载/保存构造数据是处理非默认构造性的工具。

您的问题是不同的:您需要外部状态,因为您正在尝试加载在构造过程中需要状态的对象,但它从一开始就没有被保存。如果是的话,您就可以像序列化期间一样重新创建父窗口。

我在这里看到的唯一“解决办法”是使用全局状态(即通过(线程)全局变量访问它)。

我不建议你这样做,但你现在很麻烦,所以考虑一下解决办法,即使是不好的,也是件好事。

一旦您从旧式档案中提取数据,我建议将其序列化为以下格式:

  • 保存所有所需的构造数据。
  • 序列化未绑定到GUI元素的数据结构

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45512699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档