Search code examples
c++boostconstructordestructorunique-ptr

Class object unique_ptr reset, order of destruction / construction


I have a vector of unique_ptr for an ethernet_socket class. If I reset the pointer, I am seeing the constructor called first in my logs before the destructor. Is this right, or is my boost logging lagging?

pseudo code

std::vector <boost::movelib::unique_ptr<eth_socket> > _eth_socket_vect;
_eth_socket_vect.resize(1);
_eth_socket_vect.at(0).reset(new eth_socket(host, port, delimiter, timeout, 1));     
// destructor is not called on first reset

// do some operations, then reset

_eth_socket_vect.at(0).reset(new eth_socket(host, port, delimiter, timeout, 1));

// do some more operations on new object

logs for second reset being called

20-02-28 08:44:14.312702 [info] src/eth_socket.cpp(eth_socket:10) >> started; host_num = 1  <---CONSTRUCTOR
20-02-28 08:44:14.312825 [info] src/eth_socket.cpp(open_eth_socket:67) >> started; host_num = 0
20-02-28 08:44:14.312869 [info] src/eth_socket.cpp(open_eth_socket:71) >> socket_host = 10.0.0.4; socket_port = 1337; host_num = 0
20-02-28 08:44:14.313016 [info] src/eth_socket.cpp(open_eth_socket:104) >> ended; host_num = 0
20-02-28 08:44:14.313054 [info] src/eth_socket.cpp(read_data:247) >> started; host_num = 0
20-02-28 08:44:14.313089 [info] src/eth_socket.cpp(read_data:275) >> ended; host_num = 0
20-02-28 08:44:14.313109 [info] src/eth_socket.cpp(eth_socket:38) >> ended; host_num = 1
20-02-28 08:44:14.313132 [info] src/eth_socket.cpp(~eth_socket:43) >> started; host_num = 0  <-- DESTRUCTOR
20-02-28 08:44:14.313225 [info] src/eth_socket.cpp(close_eth_socket:113) >> started; host_num = 0
20-02-28 08:44:14.313287 [info] src/eth_socket.cpp(socket_read_data_callback:368) >> started; host_num = 0
20-02-28 08:44:14.313299 [info] src/eth_socket.cpp(close_eth_socket:144) >> ended; host_num = 0
20-02-28 08:44:14.313327 [info] src/eth_socket.cpp(~eth_socket:58) >> ended; host_num = 0

Solution

  • When you resize the vector, its elements contain empty unique_ptr (equivalent to nullptr):

    std::vector <boost::movelib::unique_ptr<eth_socket> > _eth_socket_vect;
    _eth_socket_vect.resize(1);
    

    Now you create an instance of eth_socket, so its constructor is invoked:

    _eth_socket_vect.at(0).reset(new eth_socket(host, port, delimiter, timeout, 1));     
    

    Then you create another instance and replace the previous one. So, first eth_socket constructor is invoked, and then the destructor of the previous instance is called:

    _eth_socket_vect.at(0).reset(new eth_socket(host, port, delimiter, timeout, 1));