首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >存储对象列表

存储对象列表
EN

Stack Overflow用户
提问于 2009-08-21 03:10:48
回答 5查看 12K关注 0票数 5

假设我有一个泛型Object类和一个泛型List类。我想维护这些对象的列表。我应该将它们存储为List<Object>还是List<Object*>

如果我使用List<Object>,并且我有一个类似这样的方法:

代码语言:javascript
复制
if(some_condition) {
    Object obj;
    myObjectList.append(obj);
}

而且我的list类只保留了对对象的引用,所以if语句一终止,对象就会被销毁,我推送的对象就会失效。所以我最终做了一些类似这样的事情:

代码语言:javascript
复制
Object *obj = new Object;
myObjectList.append(*obj);

这样它就不会被毁掉。但现在这些对象是不可删除的,不是吗?因为现在它们被安全地存储在列表中作为对象,而不是指向对象的指针,所以我不能对它们调用delete…或者,当它们从列表中弹出时,它们会自动销毁吗?

在这种情况下,我可能应该使用List<Object*>,并在完成后将其从列表中删除,不是吗?

如此困惑..。我确信我在这里的某个地方有一个根本性的误解。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-08-21 03:15:45

编辑:在评论boost::ptr_list中提到的甚至更好,因为它更高效,并具有与std::list<boost::shared_ptr<T> >相同的净效果。

EDIT:你在评论中提到你正在使用Qt。如果你使用的是>= 4.5,你可以像这样使用Qt的QListQSharedPointer类:

代码语言:javascript
复制
QList<QSharedPointer<Object> > object_list;
object_list.push_back(QSharedPointer<Object>(new Object));

我建议您使用std::list<>。您也可能只想存储指向对象的指针,这样它们就不会一直被复制。

所以底线是:

假设您有一个名为Object的类。您应该这样做:

代码语言:javascript
复制
std::list<boost::shared_ptr<Object> > object_list;
object_list.push_back(new Object);

对于c++11/14,不需要boost,只需使用标准的智能指针:

代码语言:javascript
复制
std::list<std::shared_ptr<Object>> object_list;
object_list.push_back(std::make_shared<Object>());

通过使用共享指针,对象将在从列表中删除时自动清除(如果没有其他shared_ptrS也指向它的话)。

你可以有一台list<Object *>。但考虑到你的经验水平,我觉得引用计数的指针对你来说会容易得多。

在这种情况下,我可能应该使用List,并在用完它们后从列表中删除它们,不是吗?

是的,这是一个可行的选择,但我强烈推荐智能指针,以避免"...and将它们从列表中删除...“一步一步来。

备注:

还有你给出的示例代码:

代码语言:javascript
复制
Object *obj = new Object;
myObjectList.append(*obj);

可能不是您想要的,这会在堆上创建一个新对象,他们会在列表中放入该对象的副本。如果在那之后没有delete obj,那么你就有一个内存泄漏,因为原始指针不会自动deleted。

票数 5
EN

Stack Overflow用户

发布于 2009-08-21 03:16:43

在第一种情况下,对象被复制,只有原始对象被销毁。另一个实例保留在列表中。

在第二个版本中,您可以使用列表析构函数来删除存储的对象。

票数 3
EN

Stack Overflow用户

发布于 2009-08-21 07:29:12

就像“所有”的事情一样,没有一个答案--关键在于你想要做什么的细节,或者你的限制是什么。

如果对象是轻量级的,并且不涉及深度复制,那么将小东西存储为副本将会更有效率。否则,智能指针的开销就超出了保证范围。如果你是polymorPHic,那么你可以使用模板化列表。

如果更重要的是最大限度地减少复制,并从模板实例化中消除冗余代码,那么使用一系列智能的共享指针。

或者使用裸指针列表,使用new/delete,并仔细处理指针的所有权。

任何列表的行为都类似于列表,因此列表实现的选择取决于您在这里没有列举的因素。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1309921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档