我的代码中有一个样式问题,我想知道其他人是否遇到过。假设我有一个没有默认构造函数的类,或者有一个我不想调用的默认构造函数(出于性能和风格原因)。例如,假设这是一个 File 对象。
现在假设我有一个文件,其中包含要删除的文件名列表......我想做以下事情:
File f("foo");
for (const string& filenameToDelete : f.Lines())
File(filenameToDelete).Delete();
File 可以在构造函数或 Delete 函数中抛出 FileNotFound。我的代码必须在删除文件的第一次失败时抛出,但如果文件“foo”不存在则不能抛出(文件的缺失只是意味着没有什么可删除的)。
我希望我能写这样的东西:
try { File f("foo"); } catch (FileNotFound) { return; }
for (const string& filenameToDelete : f.Lines())
File(filenameToDelete).Delete();
但这显然不能编译。我可以这样做:
unique_ptr<File> f;
try { f.reset(new File("foo")); } catch (FileNotFound) { return; }
for (const string& filenameToDelete : f->Lines())
File(filenameToDelete).Delete();
但我有点不喜欢我需要为一个可能被堆栈分配的变量分配内存......
如果我想编写带有不进行堆分配的任意约束的代码,我只能考虑这样做:
struct FileNotFoundToRethrow : public FileNotFound {};
try
{
File f("foo");
try
{
for (const string& filenameToDelete : f.Lines())
File(filenameToDelete).Delete();
}
catch (FileNotFound)
{
throw FileNotFoundToRethrow();
}
}
catch (FileNotFoundToRethrow) { throw; }
catch (FileNotFound) { return; }
我觉得这很丑陋,很难看出我想要做的就是处理第一行抛出的 FileNotFound 异常......有更好的方法吗?