如何处理错误情况与非错误情况下的对象破坏
我有一个程序负责读取数据、格式化数据并创建记录,以及将记录输出到文件。本次讨论的重要类是:
- RecordGenerator - 包含控制主流程的线程 (获取数据、格式、输出)
- FileManager - 管理输出文件。记录发送至此 类,然后将其放入收费文件中。
- OutputFile - 包含记录的文件的抽象,具有 print()、close() 等。这些对象由 FileManager 拥有。
在正常进程关闭期间,这些类的析构函数都会被调用,这会导致所有剩余记录被刷新到当前输出文件,然后它被关闭。这确保我们不会丢失任何数据。 但是,在错误情况下,我们需要关闭,但我们不想刷新并关闭文件,因为数据可能已损坏。通常情况下,会抛出一个异常,该异常会被 RecordGenerator 捕获,然后由 RecordGenerator 决定这是否是致命错误。如果是,它将启动应用程序关闭。此时,FileManager
被破坏,但需要知道是否存在错误。同样,当FileManager
被破坏时,这会导致OutputFile
被破坏,它也需要知道是否有错误。
我的第一反应是添加一些为这些类设置错误标志的公共函数,因此 RecordGenerator 可以调用 FileManager::setErrorFlag() ,然后调用 OutputFile ::setErrorFlag()。添加这些对象链对我来说似乎是一种非常难闻的气味,特别是如果您认为对象链可能比这长得多。
有没有更好的方法来处理这种情况?
I have a program that is responsible for reading data, formatting it and creating records, and outputting records to files. The important classes for this discussion are:
- RecordGenerator - contains the thread that controls the main flow
(get data, format, output) - FileManager - manages the output files. Records are sent to this
class which then puts it in a charging file. - OutputFile - abstraction of a file that contains records, has
print(), close(), etc. These objects are owned by theFileManager
During a normal process shutdown, the destructors for these classes all get called which causes all remaining records to get flushed out to the current output file and then it gets closed. This ensures we don't lose any data.
However, during an error case, we need to shutdown but we don't want to flush and close the file since the data is likely corrupt. Normally what happens is an exception will get thrown which gets caught in the RecordGenerator
which then decides if this is a fatal error or not. If it is, it will initiate the application shutdown. It's at this point that the FileManager
gets destructed, but needs to know whether there is an error. Likewise, when the FileManager
gets destructed, this causes the OutputFile
to get destructed which also needs to know whether there is an error.
My first reaction was to just add some public functions that set error flags for these classes, so RecordGenerator
could call FileManager::setErrorFlag()
which can then call OutputFile::setErrorFlag()
. Adding a chain of these seems like a pretty bad smell to me, especially if you consider the object chain could be much longer than this.
Is there some better way of handling this sort of scenario?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当人们开始以不应该使用的方式使用 RAII 时,这是一个典型的问题。析构函数应该清理资源并恢复它们负责的任何内容。他们不应该提交更改。典型的异常安全 C++ 代码如下所示:
例如:
This is a typical problem when people start using RAII the way it's not meant to be used. Destructors should clean resources and revert whatever they are responsible to. They should not commit changes. Typical exception safe C++ code looks like this:
For example: