2

我的代码中有一个样式问题,我想知道其他人是否遇到过。假设我有一个没有默认构造函数的类,或者有一个我不想调用的默认构造函数(出于性能和风格原因)。例如,假设这是一个 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 异常......有更好的方法吗?

4

2 回答 2

1

我会用旗帜做

bool throwOnNotFound = false;

try
{
    File f("foo");

    throwOnNotFound = true;

    for (const string& filenameToDelete : f.Lines())
        File(filenameToDelete).Delete();
}
catch (FileNotFound)
{
    if (throwOnNotFound)
        throw;
}
于 2012-06-23T23:18:30.653 回答
1

对于那些觉得特别聪明的人来说,也许有一种方法可以参考 const 来延长寿命。但也有缺点。一个类必须有一个空(或默认)对象,而且,引用是const

File fooFile()
{
    try { return File("foo"); } catch (FileNotFound) { return File::Default; }
}

使用它:

const File& foo = fooFile();

if (foo.IsDefault())
    return;

for (const string& filenameToDelete : f.Lines())
        File(filenameToDelete).Delete();
于 2012-06-23T23:41:12.017 回答