gpt4 book ai didi

sockets - 管理套接字文件描述符的智能指针

转载 作者:行者123 更新时间:2023-12-03 11:58:08 25 4
gpt4 key购买 nike

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

我找到了this有用的页面,不幸的是,大多数方法对我不起作用。下面是我到目前为止找到的一个可行的解决方案,这有点讨厌。因为 uniqu_ptr 需要一个我创建的指针 int *fd 来存储 fd 值,因此,我必须在我的自定义删除器中关闭 (*fd) 并删除 fd。

(1) 有没有更好的办法?

基于上述网页提供的提示的选项 A 和 B 更好,但会导致奇怪的编译器错误。

(2) 有谁知道如何正确使用这些替代品?

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

#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 发布的答案是正确的,它解决了我最初的问题。

learnvst 的评论让我重新思考了我的问题,我不得不说我可能让它比需要的复杂得多,因为下面的简单类也应该解决我的自动释放资源内存的问题,或者像我的情况一样,关闭文件描述符:

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

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

最佳答案

因为 fd 不是指针,所以我不会尝试将它归类到 unique_ptr .相反,创建一个接口(interface)基于 unique_ptr 的自定义类。 ,如(注意:完全未经测试):

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;
};

关于sockets - 管理套接字文件描述符的智能指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29614775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com