Boost::序列化和 MFC Doc/View 架构

2024-03-10

我正在移植现有的 MFC C++ 应用程序以对 XML 文件使用 Boost::Serialization。我的 CDocument 对象包含应用程序的所有数据。我已将序列化函数实现为:

template<class Archive>
void CMyDoc::serialize(Archive& ar, const unsigned int version)
{
ar  & BOOST_SERIALIZATION_NVP(m_Param1)
    & BOOST_SERIALIZATION_NVP(m_Param2);
}

为了捕获保存和加载事件,在 CDoc *.cpp 文件中,我重载了基类函数 OnOpenDocument() 和 OnSaveDocument() 来实现 Boost::Serialization:

BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
clear();    // clear current params

//if (!CDocument::OnOpenDocument(lpszPathName)) // Old MFC serialize code
//  return FALSE;

CEvolveTrafficDoc* pDoc = this; // pointers the same here
std::ifstream ifs(lpszPathName);
boost::archive::xml_iarchive ia(ifs);
ia >> boost::serialization::make_nvp("MyDoc",pDoc); // pointer changes here
// *this = *pDoc; // POSSIBLE solution with CMyDoc copy constructor implemented

return TRUE;
}

BOOL CMyDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
//if (!CDocument::OnSaveDocument(lpszPathName)) // Old MFC serialize code
//  return FALSE;

std::ofstream ofs(lpszPathName);
boost::archive::xml_oarchive oa(ofs);
oa << boost::serialization::make_nvp("MyDoc",this);

return TRUE;
}

保存文档效果很好。问题是加载文档不起作用。 boost 库似乎复制了 CMyDoc 对象,因为指针返回了不同的地址。这意味着加载的文件未加载到当前文档中。 CDoc 可以用 boost 覆盖自身吗?它可以与 MFC CArchive 一起使用。

我考虑过将该行指示为“可能的解决方案”,但这意味着实现 CMyDoc 类的复制构造函数。这消除了 boost 的好处之一,因为我将为每个变量编写两行代码: 1. ar & BOOST_SERIALIZATION_NVP(m_Param1) // 用于保存和加载到 pDoc 2. this->m_Param1 = pDoc.m_Param1 // 在 CMyDoc 复制构造函数中

如果我重载 CMyView 来捕获文件打开和保存事件,则 Doc/View 架构提供的 MRU 列表管理将不会发生。

我确信这已经被执行了一百万次,但我在网上找不到任何信息。诡异的!非常感谢任何帮助:D


仔细阅读文档,我发现 Boost 承认任何序列化指针都使用新关键字进行反序列化:“指针的序列化是在库中实现的,代码类似于以下内容:”

// load data required for construction and invoke constructor in place
template<class Archive, class T>
inline void load_construct_data(
Archive & ar, T * t, const unsigned int file_version
){
// default just uses the default constructor to initialize
// previously allocated memory. 
::new(t)T();
}

文档建议在必要时重载此函数:

template<class Archive>
inline void load_construct_data(
Archive & ar, my_class * t, const unsigned int file_version
){
// retrieve data from archive required to construct new instance
int attribute;
ar >> attribute;
// invoke inplace constructor to initialize instance of my_class
::new(t)my_class(attribute);
}

但这又会导致需要实现 CMyDoc 复制构造函数。啊啊啊啊!!


如果它对任何人有帮助,我收到了罗伯特·雷米(Robert Ramey)对此的回复。基本上,我没有遗漏一些明显的东西:CMyDoc serialize(Archive& ar, const unsigned int version) 函数不是运行程序,因此我实现了单独的 boost_save 和 boost_load 函数。我必须重载 OnOpenDocument 和 OnSaveDocument,例如:

BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName) { 清除();

// Call base class function with empty local Serialize function
// to check file exists etc
if (!CDocument::OnOpenDocument(lpszPathName))
    return FALSE;

std::string file( lpszPathName );
boost_load(file);
return TRUE;

}

这是必要的,因为 MFC CArchive 拥有该文件,直到 MFC Serialize 函数退出,不允许 boost::serialization 访问该文件。即使在 Serialize 函数中调用 ar.Abort() 也不起作用,因为 CDocument 基类假定 ar 在返回到基类 Serialize 函数时存在。


使用 Boost.IOStreams 有一个非常简洁的解决方案:

// We mean to not track this class, or you'll get object-tracking warnings
BOOST_CLASS_TRACKING(MyDoc, boost::serialization::track_never)

void MyDoc::Serialize(CArchive& ar)
{
    namespace io = boost::iostreams;
    io::file_descriptor fd(ar.GetFile()->m_hFile, io::never_close_handle);
    io::stream<io::file_descriptor> file(fd);

    if (ar.IsStoring())
    {
        boost::archive::xml_oarchive oa(file);
        oa << *this;
    }
    else
    {
        boost::archive::xml_iarchive ia(file);
        ia >> *this;
        // then update the views...
    }
}

template<class Archive>
void MyDoc::serialize(Archive & ar, unsigned version)
{
    // Your Boost.Serialization code here
    ar & BOOST_SERIALIZATION_NVP(member);
}

您不必为 OnOpenDocument/OnSaveDocument 操心。 只需覆盖 CDocument::Serialize 并将其转发到 Boost.Serialization 即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Boost::序列化和 MFC Doc/View 架构 的相关文章

  • 如何验证文本文件中的用户名和密码? | Winforms C#

    首先我制作了textbox1 用于用户名 textbox2 用于密码 和button1 检查 后 private void button1 Click object sender EventArgs e FileStream fs new
  • 不带()的sizeof有什么作用? [复制]

    这个问题在这里已经有答案了 作者是这个问题 https stackoverflow com questions 18898410 2 dimensional array simple understanding当我问他什么时 他只是取笑我s
  • C++:初始化结构体并设置函数指针

    我正在尝试使用函数指针初始化结构 但是除非使用全局函数完成 否则我很难这样做 以下代码有效 float tester float v return 2 0f v struct MyClass Example typedef float My
  • 了解 Windows 8 上的文件何时发生更改

    我知道 FileSystemWatcher 类在 Windows 8 上不起作用 为什么在 Windows 7 上检测到 FileSystemWatcher 属性更改 而在 Windows 8 上检测不到 https stackoverfl
  • 将密码存储到sql中的最佳方法

    在我当前的 C Windows 应用程序中 密码已以纯文本形式存储 这显然不好 所以我只想知道加密密码并存储到 SQL Server 中的最佳方法是什么 我读到使用哈希 盐更好 但我觉得sql 2005中的 EncryptByPassPhr
  • 如何使用可变参数模板声明 std::tuple?

    也许我在这里很天真 但我相信以下代码应该编译 template
  • 如何使用 Moq 模拟 Web 服务调用?

    The using下面点击了我不想实际点击的外部资源 我想测试someResult以及使用它的代码 但每次我运行单元测试时 该代码仍然尝试访问真正的 Web 服务 如何使用最小起订量来伪造对 Web 服务的真实调用 但不模拟使用中的其余代码
  • 更改 RabbitMQ 队列中的参数

    我有一个 RabbitMQ 队列 最初声明如下 var result channel QueueDeclare NewQueue true false false null 我正在尝试添加死信交换 因此我将代码更改为 channel Exc
  • 如何测试抽象类的受保护抽象方法?

    我一直在研究测试名为的抽象类的最佳方法TabsActionFilter 我保证继承自的类TabsActionFilter将有一个名为GetCustomer 在实践中 这种设计似乎效果很好 我遇到的一些问题是弄清楚如何测试OnActionEx
  • 私有方法和属性的 JetBrains Rider C# 命名风格

    我想将私有方法的首字母设为小写 将公共方法的首字母设为大写 然而 在 Rider 中 C 命名风格下似乎只有一个选项可以应用所有方法 属性和事件 告诉 Rider 仅对私人使用不同约定的最佳方式是什么 也可以看看 私有方法和属性的 ReSh
  • DISM.exe 返回代码?

    我有一个程序调用 dism exe 程序 它在后台运行一些命令 现在 我只检查返回代码 0 或其他任何内容 以显示进程失败或成功 我可以用什么来交叉检查返回代码以获得准确的返回错误 DISM 参考了哪些回报 评论中提供的链接DISMAPI
  • 私有静态方法有必要吗?

    原理工程师 https stackoverflow com users 201787 metal在我上一家公司有一条规则private static方法应该作为实现文件中的函数实现 而不是作为类方法 我不记得他的规则是否有任何例外 我在目前
  • 无法加载文件或程序集“SharpSvn”或其依赖项之一。尝试加载格式不正确的程序

    我刚刚在这里下载了 64 位版本的 SharpSVNthe link http sharpsvn open collab net files documents 180 5570 SSvn 1 7002 1998 x64 zip 当我运行我
  • System.Globalization.CultureInfo 不包含 Name 的定义

    我对 System Globalization CultureInfo 类和 System Globalization 命名空间有这个特殊问题 我从具有 CultureInfo 属性的 API 调用返回一个对象 语言 我能够成功地将其在客户
  • opencv中矩阵的超快中值(与matlab一样快)

    我正在 openCV 中编写一些代码 想要找到一个非常大的矩阵数组 单通道灰度 浮点数 的中值 我尝试了几种方法 例如对数组进行排序 使用 std sort 和选择中间条目 但与 matlab 中的中值函数相比 它非常慢 准确地说 在 ma
  • 从 C++ 检索 Python 类型

    这个问题实际上是以下两个问题的延伸 如何在 Python 中实现 C 类 以供 C 调用 https stackoverflow com questions 9040669 how can i implement a c class in
  • 升压参数库

    最近我发现参数 http www boost org doc libs 1 50 0 libs parameter doc html index htmlBoost 中的库 老实说 我不明白为什么这是 Boost 的一部分 当需要向函数传递
  • 文件/文件夹结构的递归搜索

    我正在尝试为返回文件和文件夹列表的 Web 服务构建递归搜索功能 我创建了这两个方法 因此它们充当递归搜索 它首先获取顶级内容 然后将任何文件添加到 fileList 并将任何子文件夹添加到 subFoldersList 我们传入访问级别
  • K&R 之后用什么书来学习纯 C 编程? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何从 dll 导出 C++ 类? [复制]

    这个问题在这里已经有答案了 我有一个有两个重载函数的类 如何从 dll 导出它以及如何由其他 C 类使用它 我的班级是这样的 define DECLDIREXP declspec dllexport define DECLDIRIMP de

随机推荐

  • svg:svg 是什么意思?

    这是什么意思 append svg svg 我在 HTML 和 D3 代码中看到了它 是否添加了SVG插件 在 XHTML 代码中 可以使用命名空间来区分网页中包含的其他基于 XML 的语言 这里 命名空间 svg 用在标签 svg 之前
  • 使用 SWIG 将 C 结构体数组访问到 Python

    我尝试从 Python 调用现有的 C 代码 C代码定义了一个结构体B包含一个结构体数组As C 代码还定义了一个函数 该函数在调用时将值放入结构中 我可以访问数组成员变量 但它不是列表 或支持索引的东西 相反 我得到的是一个代理对象B I
  • jQuery Closest() 不适合我(或者我不为它工作)

    鉴于这个 jQuery div MvcFieldWrapper input focus function this closest label MvcDynamicFieldError fadeOut 并给出这个 HTML div clas
  • R:箱线图 - 如何向下移动 x 轴标签?

    RGR Treatment Geno boxplot fit lt aov Total RGR Treatment Geno data For R summary fit t lt TukeyHSD fit t boxplot Total
  • 用razor显示编码的html

    我将编码的 HTML 存储在数据库中 我可以正确显示它的唯一方法是 div class content MvcHtmlString Create HttpUtility HtmlDecode Model Content div 它很丑 有没
  • 使用Python将海量数据批量插入SQLite

    我读到了这个 使用 Python 将 CSV 文件导入 sqlite3 数据库表 https stackoverflow com questions 2887878 importing a csv file into a sqlite3 d
  • 如何使用 ruby​​ 将图像文件转换为字节数组

    我需要将图像作为字节数组传递到 NET SOAP Web 服务 谁能举例说明如何使用 ruby 将上传的图像文件转换为字节数组 如果我正确理解您的问题 您将获得某种格式的图像 例如 jpeg 或 png 但您需要像素数组才能发送到 SOAP
  • 在带有选项卡的 Winforms 的模型视图演示器中应该使用多少个演示器?

    我有一个带有与业务实体相关的选项卡的表单 例如一个人有传记数据 地址数据等 每个选项卡处理一类个人数据的输入 编辑 并且每个选项卡可以独立保存 应该为所有选项卡使用一名演示者 还是每个选项卡使用一名演示者 还可能有一个主选项卡 它可以导航到
  • 出现 Axios 错误:拨打大量电话时连接 ETIMEDOUT

    从我的 Azure Function 进行大量调用时出现此错误 这个错误是什么意思 如何排除故障 我猜我的 TCP 套接字用完了 我真的不知道如何在功能应用程序菜单中检查它 不过 我检查了 Azure Maps API 的日志 没有错误或掉
  • git 中带有子模块的浅克隆,如何使用指向提交而不是最新提交? [复制]

    这个问题在这里已经有答案了 我知道可以使用浅层子模块 depth选项与git submodule update 但是 如果我跑 git submodule update init recursive depth 1 在我的带有多个子模块的项
  • 如何更改动态 SQL 中的序列?

    我正在尝试创建一个脚本来将数据从一个数据库迁移到另一个数据库 我当前无法做的一件事是将序列的 nextval 设置为另一个数据库中序列的 nextval 我从 user sequences 中得到了值的差异 并生成了以下动态 SQL 语句
  • 如何从 NSArray 中选择 UIImgeView

    I have UIImageView用作可拖动对象 它们位于NSArray所以 当拖动它们时它们工作得很好 但我想要的是当我拖动它们并完成拖动方法而不是将图像放在UIImageView我只想在拖动完成时将其替换为自定义图像 所以我的问题是如
  • 具有相同高度的 SwiftUI HStack 元素

    我希望两个按钮具有相同的高度 类似于Equal HeightUIKit 中的约束 不想指定框架 让 SwiftUI 处理它 但 HStack 中的元素应该具有相同的高度 按钮应具有相同的宽度和高度 并适应较长的文本并增加其框架大小 两个按钮
  • AssemblyInstaller 中的服务类型

    我想通过编程方式安装 Windows 服务example https stackoverflow com questions 1195478 how to make a net windows service start right aft
  • 在广播接收器中检测 USB - 我缺少什么?

    我的代码遗漏了一些东西 需要你的眼睛来定位 我创建了一个 USBOnReciever 广播接收器 public class USBOnReceiver extends BroadcastReceiver Override public vo
  • wc_countries - 国家选择下拉菜单 - woocommerce

    我正在努力设置一个带有默认 WooCommerce 国家和州选择下拉列表的表单 基本上 我想显示国家 地区选择 然后根据国家 地区选择显示州选择 因此 如果用户选择英国 则会显示包含州选择的新下拉列表 我到目前为止
  • 如何保留setTimeout参数值直到执行?

    我有一些在按键时执行的代码 并在用户键入时将数据保存到数据库中 我添加了一个 setTimeout 函数 前面有一个clearTimeout 因此并非用户输入的每个字符都会发送 Ajax 请求来保存数据 虽然 setTimeout 对于一个
  • 浏览器中的 HTTP PATCH 支持

    我正在为我的应用程序设计 REST 端点 并且我需要对一些端点使用 PATCH 所有支持 HTTP 1 1 的浏览器都能够支持 PATCH 吗 HTTP 1 1 没有定义PATCH method HTTP 1 1 确实为客户端和 或服务器添
  • MySQL 中的 CAST 为 DECIMAL

    我正在尝试在 MySQL 中转换为 Decimal 如下所示 CAST COUNT 1 5 AS DECIMAL 2 我正在尝试将表中的行数 乘以 1 5 转换为该点后带有两位数字的浮点数 SQL代码 SELECT CONCAT Guard
  • Boost::序列化和 MFC Doc/View 架构

    我正在移植现有的 MFC C 应用程序以对 XML 文件使用 Boost Serialization 我的 CDocument 对象包含应用程序的所有数据 我已将序列化函数实现为 template