C++ 从STL std::队列中删除而不破坏删除的对象?

C++ 从STL std::队列中删除而不破坏删除的对象?,c++,stl,queue,C++,Stl,Queue,我可以在STL容器(队列和列表)上找到的所有文档都表明,对于任何remove函数,都会调用remove对象的析构函数。这意味着我不能在任何时候使用std::queue,因为我想要的队列只是需要对其执行某些操作的对象列表 我希望在对象排队等待我对其执行操作时,能够将对象添加到队列中。然后,当我完成它们时,我想将它们从中移除,而不会破坏正在讨论的对象。从我阅读的文档来看,这似乎是不可能的。我是否误读了文件?除了基本“队列”之外,STL中是否还有其他类型的队列在调用pop_front时不调用已删除对象

我可以在STL容器(队列和列表)上找到的所有文档都表明,对于任何remove函数,都会调用remove对象的析构函数。这意味着我不能在任何时候使用std::queue,因为我想要的队列只是需要对其执行某些操作的对象列表

我希望在对象排队等待我对其执行操作时,能够将对象添加到队列中。然后,当我完成它们时,我想将它们从中移除,而不会破坏正在讨论的对象。从我阅读的文档来看,这似乎是不可能的。我是否误读了文件?除了基本“队列”之外,STL中是否还有其他类型的队列在调用pop_front时不调用已删除对象的析构函数

编辑以澄清:在我的例子中,我使用的是指针列表。大概是这样的:

   dbObject *someObject;
   queue<dbObject *> inputQueue;
   inputQueue.push_back(someObject);

   ...

   dbObject *objectWithInput = inputQueue.front();
   //handle object's input...
   inputQueue.pop_front(); // Remove from queue... destroyed now?
dbObject*someObject;
队列输入队列;
inputQueue.push_back(someObject);
...
dbObject*objectWithInput=inputQueue.front();
//处理对象的输入。。。
inputQueue.pop_front();//从队列中删除。。。现在被摧毁了?

使用指向对象的指针列表如何?

类someobj\u t{};
class someobj_t {};

std::queue<someobj_t> q;
...

someobj_t ppd = q.front(); // ppd is not a reference
q.pop();

// ppd now contain removed object
std::队列q; ... someobj_t ppd=q.front();//ppd不是参考资料 q、 pop(); //ppd现在包含删除的对象

如果您不想复制
someobj\u t
,可以使用
std::queue

如果将指向对象的指针放在队列(以及任何其他STL容器)中,则移除指针时不会删除它们


详细说明:当您使用std::queue并删除一个对象时,会调用某个对象的析构函数。但是普通指针的析构函数(或任何POD类型-int、char等)是空的,不可操作。这里的细线是某些对象的析构函数与某些对象的析构函数非常不同

STL容器具有值语义。将对象推入STL容器时,STL容器保留其自身的对象副本,从容器中移除对象(内部副本)时,该对象将被销毁

如果使用代理类型的容器作为原始指针、智能指针(共享\u ptr、弱\u ptr)或适配器(作为boost::reference\u wrapper),则STL容器将销毁代理,但不会销毁该类型。在其他资源中选择一个通常是您希望如何处理资源的问题

最常见的习惯用法是使用原始指针,但它们没有明确说明谁负责销毁(从容器中提取的代码应该删除指针,或者在其他地方处理资源?)

现代使用转向共享的ptr方法,因为它稀释了所有权问题。当您将对象从容器中取出时,将保证该对象处于活动状态,如果没有其他人持有共享\u ptr,则当本地共享\u ptr超出范围时,该对象将自动删除。使用弱ptr将保留原始代码中的所有权,但允许您在使用前检查指针的有效性(如果已删除)。这样可以避免对将立即删除的对象执行操作

共享\u ptr/弱\u ptr方法的问题在于,它迫使您使用共享\u ptr来保存原始资源。这意味着您将无法将指针放入另一个类的子对象(成员属性),而不重新设计该类以通过共享的_ptr保存该属性,这将产生其他影响(属性在内存中不再是连续的,将需要更多的动态分配操作…)


使用适配器作为boost::reference\u包装器是一种很少见到的技术。引用包装器是一个代理对象,它包含对原始对象的引用,并且本身是可复制的。与普通原始指针相比的优势在于,读取代码时很明显资源是在队列之外管理的:从队列中提取数据的代码不需要删除对象。与智能指针方法相比,它的优点是不需要重新设计系统的其他部分来使用智能指针。缺点是,与原始指针方法一样,您必须手动确保引用对象的生存期超过容器中的引用。

将容器中的项视为该容器的“范围内”,当从容器中移除项时,就像离开函数的范围一样。如果变量是指针,则在离开作用域时,项不会发生任何变化。如果变量是堆栈局部变量,则在离开作用域时将自动调用析构函数

在容器中存储指针与将指针分配到本地原始指针具有相同的缺点,内存不会自动清理。在函数中,如果不通过返回指针来删除指针或转移所有权,则存在内存泄漏

在容器中存储原始指针时,所有权可能变得有点模糊,并且很容易发生泄漏。请看一下tr1::shared_ptr,并将其存储在容器中


C++0x中的std::unique_ptr对于在stdlib容器中存储可用的指针来说也是一个很好的解决方案。

这不是仍然调用解构器吗?这就是我正在使用的,我的大多数对象都是指向存储在代码中其他位置的对象的指针。如果将指针存储在队列中,移除它们将不会调用析构函数。类似的问题:完全正确。仅供参考,如果你真的想用容器来删除指向的对象,那么你需要存储某种智能指针,或者使用类似boost的指针容器。我喜欢你解释和措辞这个答案的方式,非常有用而且非常完整。这样真正的对象就不会在擦除时被破坏。