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

San*_*nto 15 c++ queue memory-management std

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

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

参考状态(无思考力的,所以我想它实际上并没有状态的话)是从队列中删除元素的唯一方法是调用pop().该引用还表示pop()调用该项的析构函数.

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

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

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

Gre*_*ill 33

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


小智 18

在线资源是值得你为他们支付的 - 得到一个适当的参考,如Josuttis的书.pop()不"调用析构函数" - 它只是通过调用pop_front()从队列适配器的底层表示中删除一个元素(默认情况下是std :: deque).如果弹出的东西有一个析构函数,它将在弹出的对象超出范围时使用,但队列类与它无关.

  • -1:正确但钝但不清楚. (4认同)
  • @Hassan:容器总是在从容器中移除时总是销毁它们包含的对象.总是.包含的对象是用户定义的类型,整数,指针还是智能指针无关紧要.它被破坏(或者没有任何反应,如果它没有析构函数).那么唯一的问题是破坏弹出对象实际上做了什么.对于指针,它什么都不做.`new`d对象不能是容器的内容,无论是否"插入智能指针".指向它的指针可能是容器的内容,但这是一个完全不同的东西. (3认同)

Ste*_*sop 6

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

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

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

T *off = q.front();
q.pop();
delete off;
Run Code Online (Sandbox Code Playgroud)

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