C ++ std :: queue :: pop()调用析构函数。指针类型是什么?

时间:2010-01-04 21:14:13

标签: c++ memory-management queue std

我有一个std::queue被包装为一个模板化的类来创建一个线程安全的队列。我有这个类的两个版本:一个存储值类型,一个存储指针类型。

对于指针类型,我在销毁时删除队列中的元素时遇到问题。原因是我不知道如何安全地从队列中删除项目。

This引用状态(空洞,所以我猜它实际上并不是STATE),从队列中删除元素的唯一方法是调用pop()。该引用还说pop()调用该项的析构函数。

嗯,这会导致我的指针类型出现问题,因为它们可能会或可能不会指向聚合。如果其中一个指向聚合,它们都会,但由于包装是模板化的,因此无法保证我们正在处理哪种类型(聚合或非聚合)。

那么,当pop()调用析构函数时,会发生什么?如何确保正确删除所有内容并正确释放内存?

最后,我的解决方案是使用旧版本的GCC for ARM9。我无法控制这一点。我知道有些库有智能指针和容器可以在这里提供帮助,但它们对我来说是禁止的。

3 个答案:

答案 0 :(得分:32)

指针本身实际上没有析构函数,因此在包含指针的队列上调用pop()将不会调用指针指向的对象的析构函数。

答案 1 :(得分:16)

在线资源非常值得为您付出代价 - 获得适当的参考资料,例如Josuttis's book。 pop()不“调用析构函数” - 它只是通过调用pop_front()从队列适配器的底层表示中删除一个元素(默认情况下为std :: deque)。如果弹出的东西有析构函数,当弹出的对象超出作用域时将使用它,但队列类与它无关。

答案 2 :(得分:3)

“我如何确保删除所有内容并正确释放内存?”

如果你必须在队列中存储指针,并且希望它们在pop时自动释放,那么你需要一个存储一个对象的队列而不是一个指针队列。指针,并在析构函数中删除它。例如,您可以使用shared_ptr队列。 shared_ptr不在标准库中,但它是TR1的一部分,并且可以广泛使用。

否则,调用者有责任删除该对象:

T *off = q.front();
q.pop();
delete off;

总结是指向动态分配对象的指针的容器有点尴尬。如果您可以设计程序以便容器存储对象的副本,而不是指向动态对象的指针,那么就这样做。如果做不到这一点,你负责资源所有权,而不是容器。 STL容器对所有权一无所知,只是复制并销毁他们的value_type。复制和销毁指针对它们指向的对象没有任何作用。