20

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

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

这个参考声明(空洞,所以我猜它实际上并没有声明它)从队列中删除元素的唯一方法是调用pop(). 该参考资料还说pop()调用了该项目的析构函数。

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

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

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

4

3 回答 3

37

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

于 2010-01-04T21:18:58.913 回答
22

在线资源物有所值 - 获得像Josuttis 的书这样的适当参考。pop() 不会“调用析构函数”——它只是通过调用 pop_front() 从队列适配器的底层表示(默认情况下为 std::deque)中删除一个元素。如果被弹出的东西有析构函数,它会在弹出的对象超出范围时使用,但队列类与它无关。

于 2010-01-04T21:24:44.517 回答
6

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

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

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

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

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

于 2010-01-04T21:37:05.740 回答