如何处理不正确的输入文件

时间:2013-04-09 20:56:34

标签: c++ exception

我正在启动一个项目,我想知道在文件输入处理期间处理错误的最佳实践。我目前的项目计划涉及main中的一个过程:

unique_ptr<Configuration> config(initConfig(argc,argv));
unique_ptr<InterfaceA> a(initA(config));

// Do real work here

Configuration类和所有其他类的初始化数据将包含在其输入文件的标题中,例如:

#ObjectA-1

ObjectA告诉我,我有一个文件要转换为满足InterfaceA的对象,1告诉我该接口的具体实现。

我的问题是对initConfiginitA等功能的错误处理。在这些函数内部,我将解析它们各自文件的第一行,并解码上述信息。如果,让我们说,在initA我碰巧得到的文件没有合适的标题,不管是#ObjectB-3,还是根本没有标题。我看到了处理错误的两种方法:

  • 抛出将在main中捕获的异常。这将允许我打印错误,然后通过错误标志绕过其他init函数,并执行我需要的任何高级清理。其中不好的一点是我的main主要是由异常处理构成的,这使得代码更难以阅读。

  • 从init函数内部打印错误,然后调用exit(EXIT_FAILURE)并依靠我的操作系统来清理以前分配的内存。这可能会导致更清晰的代码和更多的本地错误处理。

如果不是使用exit函数,我个人更喜欢第二种。

1 个答案:

答案 0 :(得分:1)

我使用以下规则来执行错误处理:

  1. 如果可以的话,调用代码应该处理这种情况吗?如果是这样,抛出异常。有时候“特殊”很难定义,所以想想它更像是“这应该发生吗?”我认为在这种情况下你应该抛出异常而main应该处理它们如果它是有意义的。

    标准定义了两组例外。首先是那些继承自std::logic_error的人。当调用代码破坏了函数的契约时,通常会抛出这些。然后是继承自std::runtime_error的那些,它们用于只能在运行时检测到的错误。这听起来和你的完全一样。它只知道文件读取时存在问题。

    当然,如果您愿意,可以抛出自己的异常类型。

  2. 这是一个被认为是正常的错误,可能会被调用代码忽略吗?这可能是错误代码的恰当使用。

  3. 这是代码内部的逻辑错误吗?这更有意义assert。您应该使用assert来验证您所做的事情是否合理。一个愚蠢的例子是int y = 5; y++; assert(y == 6);。把它想象成对愚蠢错误的保险。

  4. 正如我所说,你的问题听起来像是一个使用异常的好地方。如果正确使用RAII,内存分配应该绝对没有问题。也就是说,所有内存释放都应该在对象的销毁中完成。即使抛出异常,仍然会调用析构函数。