C++在析构函数中序列化是一个坏主意,如果是这样,为什么呢?

Æle*_*lex 3 c++ serialization destructor boost-serialization

通过在类的命令中调用保存函数(ala boost-serialize)可能会产生什么负面/未定义的行为?

Ste*_*sop 7

你有两个顾虑,其中一个是另一个的结果:

1)您不应允许任何异常逃避析构函数.如果你这样做,并且如果析构函数被作为堆栈展开的一部分被调用,那么运行时将是terminate()你的程序.这不是未定义的行为,但它非常消极.

因此(当然也因为析构函数不返回值):

2)你的析构函数没有合理的方法来指示成功或失败("合理"的意思,没有构建某种单独的错误报告系统).由于您的类的用户可能想知道保存是否发生,最好使用合理的API来执行此操作,这意味着析构函数只能在"尽力而为"的基础上保存数据.如果保存失败,那么对象仍然会被破坏,因此可能会丢失其数据.

对于这种情况存在策略,例如由文件流使用.它的工作原理如下:

  • flush()(或在你的情况下save())保存数据的功能
  • 如果对象尚未被保存/刷新,则从析构函数中调用此函数(或者更可能:无条件地调用它,但让函数本身知道它是否需要执行任何实际工作).在文件流的情况下,这发生在close().捕获它可以抛出的任何异常并忽略任何错误.

这样,需要知道保存是否成功的用户save()才能查出.不关心的用户(或者如果可能的话,在抛出异常并且对象作为堆栈展开的一部分被销毁的情况下不会介意它成功的用户)可以让析构函数尝试.

也就是说,你的析构函数可以尝试做一些可能失败的事情,作为最后的努力,但你应该另外提供一种方法让用户"正确地"做同样的事情,以告知他们成功或失败.

是的,这确实意味着使用流而不刷新它们并检查流状态是否失败并不是"正确"使用它们,因为您无法知道数据是否曾被写入.但是在某些情况下,这种情况已经足够好了,在同样的情况下,你的类可能足以保存它的析构函数.