【问题标题】:Class object unique_ptr reset, order of destruction / construction类对象 unique_ptr 重置,破坏/构造顺序
【发布时间】:2020-06-12 17:03:19
【问题描述】:

我有一个unique_ptr 的向量,用于ethernet_socket 类。如果我重置指针,我会在日志中看到在析构函数之前首先调用的构造函数。这是对的,还是我的 boost 日志记录滞后?

伪代码

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

调用第二次重置的日志

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

【问题讨论】:

  • 第一个reset 不会释放eth_socket。 vector 在resize(1) 之后包含一个“空”unique_ptr
  • 首先创建新的socket对象,然后用它替换指针,此时之前的socket正在销毁。
  • 伙计,这应该很明显。在调用方法之前必须先评估参数,因此 new eth_socket 必须在调用 reset 之前完成,这可以释放旧对象。
  • @MarekR 哦,我明白了,新的类对象被创建了,然后原来的被销毁并被新的替换,因此构造函数在析构函数之前调用,相对而言
  • @xinthose 我很确定您也使用了很多标准库中的内容,因此您可以争辩说,当 boost 和标准之间存在重叠时,请使用标准。

标签: c++ boost constructor destructor unique-ptr


【解决方案1】:

当你调整vector的大小时,它的元素包含空的unique_ptr(相当于nullptr):

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

现在你创建了一个eth_socket 的实例,所以它的构造函数被调用:

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

然后您创建另一个实例并替换前一个实例。所以,首先调用eth_socket构造函数,然后调用前一个实例的析构函数:

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

【讨论】:

  • 你不是说秒eth_socket构造函数被调用,然后之前实例的析构函数被调用?
  • @xinthose 按照事件顺序,它是 first。不是第一个eth_socket构造函数...。
猜你喜欢
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 2016-12-31
  • 2015-05-12
  • 2012-12-15
  • 1970-01-01
  • 2014-08-12
  • 2013-09-04
相关资源
最近更新 更多