用于管理套接字文件描述符的智能指针 [英] smart pointer to manage socket file descriptor

查看:92
本文介绍了用于管理套接字文件描述符的智能指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果指针超出范围,智能指针将清除内存.我想让它适应文件描述符,例如套接字.在那里,您需要一个用户定义的删除器,因为close()是释放文件描述符(fd)资源的函数.

A smart pointer clears the memory if the pointer gets out of scope. I wanted to adapt this to a file descriptor, like a socket. There you need a user defined deleter, because close() is the function to free the file descriptor (fd) resources.

我发现了有用的页面,不幸的是,大多数方法对我来说都不起作用.下面是我到目前为止找到的有效解决方案,有点讨厌.由于uniqu_ptr期望我创建一个int * fd指针来存储fd值,因此,我不得不关闭(* fd)并在自定义删除器中删除fd.

I found this useful page, unfortunately, most approaches did not work for me. Below is a working solution I found up to now, which is a little nasty. Because uniqu_ptr expects a pointer I created int *fd to store the fd value, therefore, I had to close(*fd) and delete fd in my custom deleter.

(1)有更好的方法吗?

选项A和B基于所提到的网页提供的提示,虽然更好,但会导致奇怪的编译器错误.

Options A and B, which are based on the hints provided by the mentioned web page, are much nicer but causing odd compiler errors.

(2)?有人知道如何正确使用这些替代方法吗?

(2) Does anyone know how to correctly use these alternatives?

我正在使用带有CONFIG + = c ++ 11选项和gcc版本4.8.2的Qt Creator 3.0.1

I'm using Qt Creator 3.0.1 with CONFIG += c++11 option and gcc version 4.8.2

#include "ccommhandler.h"

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <memory>

#include <qdebug.h>

//for Option A and B
struct CloseHandleDeleter {
    typedef int pointer;
    void operator()(int handle) const
    {
    }
};

//custom deleter, working
class MyComplexDeleter
{

public:
    MyComplexDeleter() {}

    void operator()(int* ptr) const
    {
        qDebug() << "Deleting ";
        close(*ptr);
        delete ptr;
    }
};

CCommHandler::CCommHandler()
{
    //Option A doesn't work
    //std::unique_ptr<int, CloseHandleDeleter> file( socket(AF_INET, SOCK_STREAM, 0) );
    //Option B doesn't work
    //std::unique_ptr<int, int()(int)> filePtr(  socket(AF_INET, SOCK_STREAM, 0) , close);

    MyComplexDeleter deleter;
    int *fd = new int;
    *fd = socket(AF_INET, SOCK_STREAM, 0);
    std::unique_ptr<int, MyComplexDeleter> p( fd , deleter);

}

内文(Nevin)发布的答案是正确的,它解决了我最初的问题.

The posted answer by Nevin is right, it solves my initial problem.

learnvst的评论重新考虑了我的问题,我不得不说我可能使它变得比所需的复杂得多,因为下面的简单类也可以解决我的问题,即自动释放资源的内存或我的情况下,关闭文件描述符:

The comment of learnvst caused to rethink my problem, and I have to say I may made it much more complex than needed, because the following simple class should also solve my problem of auto-free the memory of a resource or as in my case, to close the file descriptor:

class SocketHandler
{
   int _fd;
 public:
   SocketHandler(int FD):_fd(FD){}
   ~SocketHandler() { if(_fd!=-1) close(_fd); }

   operator int() const { return _fd; }
};

推荐答案

由于fd不是指针,因此我不会尝试将其归入 unique_ptr .而是创建一个基于 unique_ptr 的接口的自定义类,如下所示(警告:完全未经测试):

Because fd isn't a pointer, I wouldn't try to pigeonhole it into unique_ptr. Instead, create a custom class whose interface is based on unique_ptr, as in (caution: totally untested):

class unique_fd
{
public:
    constexpr unique_fd() noexcept = default;
    explicit unique_fd(int fd) noexcept : fd_(fd) {}
    unique_fd(unique_fd&& u) noexcept : fd_(u.fd_) { u.fd_ = -1; }

    ~unique_fd() { if (-1 != fd_) ::close(fd_); }

    unique_fd& operator=(unique_fd&& u) noexcept { reset(u.release()); return *this; }

    int get() const noexcept { return fd_; }
    operator int() const noexcept { return fd_; }

    int release() noexcept { int fd = fd_; fd_ = -1; return fd; }
    void reset(int fd = -1) noexcept { unique_fd(fd).swap(*this); }
    void swap(unique_fd& u) noexcept { std::swap(fd_, u.fd_); }

    unique_fd(const unique_fd&) = delete;
    unique_fd& operator=(const unique_fd&) = delete;

    // in the global namespace to override ::close(int)
    friend int close(unique_fd& u) noexcept { int closed = ::close(u.fd_); u.fd_ = -1; return closed; }

private:
    int fd_ = -1;
};

这篇关于用于管理套接字文件描述符的智能指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆