c++ - How to set up a std container with a RAII class? -
to realize raii idiom type socket
, have created wrapper. wrapper calls connect
in constructor , closesocket
in destructor. std::map
holds used sockets. unfortunatelly inserting new socket container calls destructor of temporary and, in fact, closes opened socket. there common way overcome this?
here code:
#include <iostream> #include <stdexcept> #include <map> #include <winsock2.h> struct socket { socket msock; socket() : msock(invalid_socket) {} socket(std::string ip, int port); ~socket(); }; socket::socket(std::string ip, int port) { msock = socket(af_inet, sock_stream, 0); if (msock == invalid_socket) throw std::runtime_error("socket()"); sockaddr_in addr = {0}; addr.sin_family = af_inet; addr.sin_port = htons(port); addr.sin_addr.s_addr = inet_addr(ip.c_str()); if (connect(msock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == socket_error) throw std::runtime_error("connect()"); std::cout << msock << " connected" << std::endl; } socket::~socket() { if (msock != invalid_socket) { closesocket(msock); std::cout << msock << " closed" << std::endl; } } int main() { wsadata wsa; wsastartup(makeword(2, 0), &wsa); std::map<int, socket> outbound; // calls constructur destructor outbound[0] = socket("192.168.128.125", 4023); wsacleanup(); return 0; }
and output is:
1952 connected 1952 closed 1952 closed
resource guards may stored in stl containers if wrap them in smart pointer. smart pointer use environment, i'd recommend go boost::shared_ptr starting point if you're not sure.
following way conform both resource guard semantics (only 1 instance manages resource's lifetime) , stl container (keep equivalent copy of passed item).
Comments
Post a Comment