我想围绕文件描述符创建一个 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/