在 shared_ptr 中包裹一个不透明的指针

Wrap an opaque pointer in a shared_ptr

我正在尝试使用 winsock2 实现一个简单的 TCP 服务器应用程序。为此,我有一个接受连接 (TcpServer) 的 class 和一个处理连接 (TcpListener) 的 class。为此这些对象需要共享SOCKET,whis被定义为UINT_PTR。要安全地分享这个 shared_ptr 似乎是要走的路。不幸的是,shared_ptr 似乎应该包含 structclass,因此我的实现如下。

struct SafeSocket_
{
    SOCKET Socket;
    SafeSocket_(SOCKET socket)
        : Socket(socket)
    {}
    ~SafeSocket_()
    {
        closesocket(Socket);
        std::cout << "destroyed SafeSocket_" << std::endl;
    }
};
typedef std::shared_ptr<SafeSocket_> SafeSocket;

为了create/accept 一个新套接字,我使用了以下可怕的代码。更糟糕的是,我需要到处使用 ClientSocket->Socket

SafeSocket ClientSocket = SafeSocket(new SafeSocket_(accept(ListenSocket, NULL, NULL)));

除了使用漂亮的包装器库之外,必须有更好的方法来处理这个问题。

注意:我知道有很好的包装器库,例如来自 boost 的 asio,但我只是想了解一些 C++ 基础知识。

基本问题是 UINT_PTR 不是不透明指针。它是一个整数。如果它是 typedef struct __socket SOCKET;,那么你可以只写 std::shared_ptr<decltype(*SOCKET{})>,坚持自定义删除器调用 close_socket,你会笑的。

有多种可能的方法:

  • 使 SafeSocket 成为包含 shared_ptr 且具有 socket 成员函数的 class。然后你到处写ClientSocket.socket()
  • 同上,但提供 SafeSocket 版本的套接字函数,它提供了实际的套接字参数。所以你写 ClientSocket.read(...).
  • 而不是 read( ClientSocket.Socket, ...)
  • 还原为 SafeSocket 作为 typedef,但将附加函数放在 SafeSocket_ 中,因此您编写 ClientSocket->read(...)

我想我更喜欢中间的解决方案。