从对象本身的容器中删除对象

Remove object from container from within the object itself

本文关键字:对象 删除      更新时间:2023-10-16

我有一个类Client,它在线程中做一些事情(方法run(。

所有客户端都是列表中的存储。

当客户端完成其工作时,我希望将其从存储它的列表中删除。

到目前为止,我得出了什么:

class Client
{
public:
Client(std::list<Client> &clients_)
: thread(&Client::run, this),
clients(clients_)
{}
~Client()
{
thread.join();
}
void run()
{
// The client does stuff here.
clients.remove(*this);
}
private:
std::thread thread;
std::list<Client> &clients;
};

int main()
{
std::list<Client> clients;
clients.emplace_back(clients);
}

在此代码中,客户端从run函数末尾的列表中删除自身。

这以某种方式起作用。我以为不会,因为clients.remove会打电话给Client::~Client,这将等待run完成。

这真的安全吗?如果没有,是否有正确的方法可以做到这一点,知道只有Client知道何时应该将其从列表中删除?

这真的很不安全,因为您将在执行"run"的线程中调用客户端析构函数,因此该线程将尝试加入自己,这是非法的。

最简单的方法是分离线程,这样它就不必连接并且应该可以工作。此外,您应该使用一些线程安全列表,因为一些客户端可能会尝试从并行线程中删除自己。

但它也不是很酷。我建议使用共享列表重新考虑这个想法,该共享列表拥有可以从不同线程中将自己从该列表中删除的对象。 这里的主要问题是你应该对客户端对象的所有权做一些事情,这样它们就不会触发自己的析构函数,这通常是一个坏主意。