c++ - 如何在不创建新 int 的情况下设计 RAII 文件描述符

标签 c++ c++11 file-descriptor raii

我想围绕文件描述符创建一个 RAII 包装器。由于该对象可能会在线程中传递,因此它确实是一种共享资源:这就是为什么我使用带有自定义析构函数的 shared_ptr 进行了第一个实现。

struct file_descriptor
{
    file_descriptor( const std::string & pathname, int flags )
        :m_fd( initialize( pathname, flags ) )
    {
    }

    file_descriptor( const int opened_fd )
        :m_fd( initialize( opened_fd ) )
    {
    }

    operator int() const { return *m_fd; }

private:
    std::shared_ptr<int> initialize( const int opened_fd )
    {
        std::shared_ptr<int> ptr_to_fd;

        try
        {
            int * shared_fd = new int;
            ptr_to_fd = std::shared_ptr<int>( shared_fd, file_descriptor_closer() );
            *shared_fd = opened_fd;
        }
        catch( std::bad_alloc & )
        {
            close( opened_fd );
            throw;
        }

        return ptr_to_fd;
    }

    std::shared_ptr<int> initialize( const std::string & pathname, int flags )
    {
        const int fd = open( pathname.c_str(), flags );        
        if (fd < 0)
            throw std::system_error( std::error_code(errno, std::system_category() ), "cannot create file descriptor" );

        return initialize( fd );
    }
    std::shared_ptr<int> m_fd;
};

自定义析构函数,非常简单:

struct file_descriptor_closer
{
    void operator()(int * const fd) noexcept { if (fd) close(*fd); delete fd; }
}; 

现在我发现这个设计很糟糕,也就是因为“new int”。我想过制作一个自定义分配器来指向一个已经分配的 block ,但这似乎有点过分了。你们有什么建议来简化这个吗?

最佳答案

恕我直言,您在混淆责任。让您的 RAII 类处理文件描述符的打开和关闭。让其他类(class)处理您的 RAII 类(class)的生命周期问题。正如您现在所拥有的,您的 file_descriptor 类的用户需要知道它正在使用 shared_ptr。在内部。乍一看,如果我要在线程之间共享一个 file_descriptor,我会生成一个 shared_ptr<file_descriptor>。我自己来解决这个问题,我真的不知道它在内部已经在做一个。

关于c++ - 如何在不创建新 int 的情况下设计 RAII 文件描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22120487/

相关文章:

c++ - 模板模板参数的模板参数推导错误

c++ - 在这种特殊情况下,我是否需要共享内存中的原子类型?

bash - 从 Bash 函数返回文件描述符

c - 从 C 中的文件描述符读取

c++ - 将 decltype 与成员函数指针一起使用

c++ - B树搜索引用子级数据类型问题

c++ - 转换 T-s 时完美转发非 T 参数

c++11 - 将 std::hash 专门化为派生类

当 push_back 新元素到 std::vector 时,C++ 引用发生变化

c - 从文件读取时出错