调用remove()来删除析构函数中的文件是否安全?

时间:2015-03-26 20:44:04

标签: c++ exception file-io destructor stdio

我有一个类,当调用某些成员函数时会创建一些临时文件。我想要在类超出范围时(通常或由于异常)删除这些文件,所以我想在析构函数中删除它们:

#include <cstdio>
#include <string>
class MyClass
{
    //implementation details

    //Names of temp files
    std::string tempFile1, tempFile2,tempFile3;

    ~MyClass()
    {
         remove(tempFile1.c_str());
         remove(tempFile2.c_str());
         remove(tempFile3.c_str());
    }
};

问题是如果由于异常而调用析构函数,那么很可能并非所有3个临时文件都已创建。根据{{​​3}},在这种情况下,remove()函数将返回非零值并向stderr写入内容。但由于它是一个C函数,因此不会成为例外。

我知道析构函数不应该抛出。这样的错误怎么样?是否建议编写类似这样的析构函数?

2 个答案:

答案 0 :(得分:3)

您展示的内容可以正常使用。但我通常更喜欢更多的RAII方法,例如:

#include <cstdio>
#include <string>

struct RemovableFile
{
    std::string fileName;
    bool canRemove;

    RemovableFile() : canRemove(false) {}
    ~RemovableFile(){ if (canRemove) remove(fileName.c_str()); }
};

class MyClass
{
    ...
    //Names of temp files
    RemovableFile tempFile1, tempFile2, tempFile3;
    ...
};

void MyClass::doSomething()
{
    ...
    tempFile1.fileName = ...;
    ...
    if (file was created)
        tempFile1.canRemove = true;
    ...
};

或者更像是这样的东西:

#include <cstdio>
#include <string>
#include <fstream>

struct RemovableFile
{
    std::string  fileName;
    std::fstream file;

    ~RemovableFile() { if (file.is_open()) { file.close(); remove(fileName.c_str()); } }

    void createFile(const std::string &aFileName)
    {
        file.open(aFileName.c_str(), ...);
        fileName = aFileName;
    }
};

class MyClass
{
    ...
    //Names of temp files
    RemovableFile tempFile1, tempFile2, tempFile3;
    ...
};

void MyClass::doSomething()
{
    ...
    tempFile1.createFile(...);
    ...
};

答案 1 :(得分:1)

C库函数remove和C ++析构函数之间没有交互。

除非

  • 你正在编写一个C库,并在C ++中进行,上面的MyClass是实现的一部分,因此调用remove会触发一些不良的重入或其他东西。 )

  • 你在一个信号处理程序中执行此操作,该处理程序在调用C库期间关闭,在这种情况下,C ++析构函数方面没有实际意义。您无法从信号处理程序中调用remove

  • 您正在抛出跨越C库激活帧的异常。那可能不好。

remove函数肯定不会打印任何内容,即使它失败了。您误解了cplusplus.com参考文本。它指的是代码示例,而不是函数。代码示例是打印消息的内容。