2009-10-14 36 views
1

如果我有一个list<object*>>* queue,并希望弹出第一个对象列表,并把它交给该计划的另一部分,是正确使用(粗略的代码):澄清名单和删除元素

object* objPtr = queue->first(); 
queue->pop_first(); 
return objPtr; // is this a pointer to a valid memory address now? 

根据有关http://www.cplusplus.com/reference/stl/list/pop_front/的文档,它调用了已删除元素的析构函数,但我很困惑它是指链表的节点对象还是实际存储的“用户”对象。

编辑:我可能是front而不是first,我的不好。

回答

3

是的,它是一个有效的指针。列表不会释放您分配的内存。列表将销毁其内部而不是用户对象。

0

您的代码很好,但最好使用list< boost::shared_ptr<object> >


    shared_ptr < object> objPtr = queue->first(); 
    queue->pop_first(); 
    return objPtr; 
+0

为什么这是低票? – sbi 2009-10-14 13:04:11

+0

我没有downvote,但这里是我的观点:你不能简单地从原生指针切换到shared_ptr,所以这个答案不是很有用。 – foraidt 2009-10-14 13:34:48

+0

为什么当你不完全了解需求时使用shared_ptr会更好。 – VNarasimhaM 2009-10-14 13:35:51

3

是它是有效的:既然你把指针到列表中,只有指针被摧毁,而不是对象本身。

0

当您删除元素时,STL容器不会销毁堆中分配的用户对象。

class A 
{ 

}; 


list<A*> PointerToObjectList; 

A* ptr = new A(); 
PointerToObjectList.push_back(ptr); 

如果您从列表中删除ptr,列表将不会自动删除该对象。一旦对象不再使用,您需要显式调用delete。

2

objPtr包含指向有效内存的指针。

将元素插入到std::list中时,list将其复制一份。在你的情况下,元素是一个地址(一个指针),所以列表会复制地址并存储它。现在

object * optr = queue->pop_front(); 

OPTR指向的对象

queue->pop_front(); 

将删除list所述元件(地址/指针),optr已指向到对象。

完成对象后,请不要忘记删除它,否则最终会导致内存泄漏。

实施例:

#include <iostream> 
#include <list> 

using namespace std; 

struct A 
{ 
    static int count; 

    A() : val(count++) { cout << "A(" << val << ")" << endl; } 
    ~A()    { cout << "~A(" << val << ")" << endl; } 

    int val; 
}; 

int A::count = 0; 

ostream& operator<<(ostream& os, A& a) { return os << a.val; } 

int main() 
{ 
    list<A*> alist; 

    for (unsigned int i = 3; i; --i) alist.push_back(new A()); 
    for (unsigned int i = 3; i; --i) 
    { 
     A * aptr = alist.front(); 
     alist.pop_front(); 
     cout << *aptr << endl; 
     delete aptr; 
     aptr = 0; 
    } 
} 
2

标准确实说(23.2.2.3/5),该元素的类型的析构函数被调用。但是这种类型在这里是一个指针,并且指针的析构函数什么都不做......