我可以在STL容器(队列和列表)上找到的所有文档都说,对于任何remove函数,都会调用被删除对象的析构函数.这意味着每当我想要一个只需要对它们执行某些操作的对象列表的队列时,我就不能使用std :: queue.
我希望能够在排队让我对他们做某事时将对象添加到队列中.然后我想在完成它们之后将它们从它上移除,而不会破坏有问题的物体.从我读过的文档中看似不可能.我误读了文档吗?除了在调用pop_front时没有调用被删除对象的析构函数的基本"队列"之外,STL中是否存在另一种类型的队列?
编辑澄清:在我的情况下,我正在使用指针列表.像这样的东西:
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?
Run Code Online (Sandbox Code Playgroud)
sbk*_*sbk 17
如果将指针放入队列中的对象(以及任何其他STL容器),则删除指针时不会删除指针.
详细说明:当你使用std :: queue并删除一个对象时,会调用some_obj*的析构函数.但是普通指针(或任何POD类型 - int,char等)的析构函数是空的,无操作.这里的细线是some_obj*的析构函数与some_obj的析构函数非常不同.
STL容器具有值语义.当您将对象推入STL容器时,STL容器会保留它自己的对象副本,并且当从容器中删除对象(内部副本)时,它将被销毁.
如果您使用代理类型的容器,作为原始指针,智能指针(shared_ptr,weak_ptr)或适配器(作为boost :: reference_wrapper),那么STL容器将破坏代理但不破坏类型.选择其中一个通常取决于您希望如何处理资源.
最常见的习惯是使用原始指针,但是他们没有明确谁负责破坏(从容器中提取的代码应该删除指针,或者资源是在其他地方处理的?).
现代使用趋向于shared_ptr方法,因为它稀释了所有权问题.当您将对象从容器中取出时,该对象将保证处于活动状态,如果没有其他人拥有shared_ptr,则当本地shared_ptr超出范围时,该对象将自动被删除.使用weak_ptr将保留原始代码中的所有权,但允许您在使用之前检查指针的有效性(如果已删除).这可以允许您避免对将立即删除的对象执行操作.
shared_ptr/weak_ptr方法的问题在于它强制您使用shared_ptr来保存原始资源.这意味着您无法将指针放入另一个类的子对象(成员属性)而无需重新设计类以通过shared_ptr保存属性,并且这将具有其他含义(属性将不再在内存中连续) ,将需要更多的动态分配操作...)
一种难以看到的技术是使用适配器作为boost :: reference_wrapper <>.引用包装器是一个代理对象,它包含对原始对象的引用,并且本身是可复制的.与普通原始指针相比,优势在于读取代码很明显资源是在队列外部管理的:从队列中提取数据的代码不需要删除对象.智能指针方法的优势在于您无需重新设计系统的其他部分即可使用智能指针.缺点是,与原始指针方法一样,您必须确保引用对象的生命周期手动超过容器中的引用.
| 归档时间: |
|
| 查看次数: |
8004 次 |
| 最近记录: |