在shared_ptr中包装不透明指针

时间:2015-12-13 13:26:49

标签: c++ std shared-ptr winsock2

我正在尝试使用winsock2实现一个简单的TCP服务器应用程序。为此,我有一个接受连接(TcpServer)的类和一个处理连接的类(TcpListener)。为此,这些对象需要共享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;

要创建/接受新套接字,我使用以下可怕的代码。更糟糕的是,我需要在整个地方使用ClientSocket->Socket

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

除了使用一个漂亮的包装库之外,还有一种更好的方法来处理它。

注意:我知道有很好的包装库喜欢来自boost的asio,但我只是搞乱了解一些C ++基础知识。

1 个答案:

答案 0 :(得分:0)

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

有许多可能的方法:

  • 使SafeSocket成为包含shared_ptr且具有socket成员函数的类。然后你就到处写ClientSocket.socket()
  • 如上所述,但是给出SafeSocket版本的套接字函数,它提供了实际的socket参数。因此,您需要read( ClientSocket.Socket, ...)而不是ClientSocket.read(...)
  • 恢复为SafeSocket作为typedef,但将其他功能放在SafeSocket_中,以便您编写ClientSocket->read(...)

我认为我最喜欢中间解决方案。