我注意到RAII在Stackoverflow上引起了很多关注,但是在我的圈子(主要是C++)中,RAII如此明显,就像问什么是类还是析构函数。

因此,我真的很好奇,是否是因为我每天都被核心C++程序员所包围,而RAII并不是众所周知的(包括C++),或者是否对Stackoverflow的所有这些质疑是由于事实我现在正与没有随C++一起成长的程序员联系,而在其他语言中,人们只是不使用/不了解RAII?

最佳答案

对于在此主题中对RAII(资源获取正在初始化)发表评论的人,这是一个激励性的例子。

class StdioFile {
    FILE* file_;
    std::string mode_;

    static FILE* fcheck(FILE* stream) {
        if (!stream)
            throw std::runtime_error("Cannot open file");
        return stream;
    }

    FILE* fdup() const {
        int dupfd(dup(fileno(file_)));
        if (dupfd == -1)
            throw std::runtime_error("Cannot dup file descriptor");
        return fdopen(dupfd, mode_.c_str());
    }

public:
    StdioFile(char const* name, char const* mode)
        : file_(fcheck(fopen(name, mode))), mode_(mode)
    {
    }

    StdioFile(StdioFile const& rhs)
        : file_(fcheck(rhs.fdup())), mode_(rhs.mode_)
    {
    }

    ~StdioFile()
    {
        fclose(file_);
    }

    StdioFile& operator=(StdioFile const& rhs) {
        FILE* dupstr = fcheck(rhs.fdup());
        if (fclose(file_) == EOF) {
            fclose(dupstr); // XXX ignore failed close
            throw std::runtime_error("Cannot close stream");
        }
        file_ = dupstr;
        return *this;
    }

    int
    read(std::vector<char>& buffer)
    {
        int result(fread(&buffer[0], 1, buffer.size(), file_));
        if (ferror(file_))
            throw std::runtime_error(strerror(errno));
        return result;
    }

    int
    write(std::vector<char> const& buffer)
    {
        int result(fwrite(&buffer[0], 1, buffer.size(), file_));
        if (ferror(file_))
            throw std::runtime_error(strerror(errno));
        return result;
    }
};

int
main(int argc, char** argv)
{
    StdioFile file(argv[1], "r");
    std::vector<char> buffer(1024);
    while (int hasRead = file.read(buffer)) {
        // process hasRead bytes, then shift them off the buffer
    }
}

在这里,当创建StdioFile实例时,获取资源(在这种情况下为文件流);销毁资源后,资源将被释放。不需要tryfinally块;如果读取导致异常,则会自动调用fclose,因为它位于析构函数中。

当函数离开main时,无论是正常还是异常,都可以保证调用析构函数。在这种情况下,将清除文件流。世界再次安全。 :-D

关于c++ - 除C++外,其他语言的程序员是否使用,了解或理解RAII?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/165723/

10-11 02:37
查看更多