【问题标题】:Pointers to objects in a set or in a vector - does it matter?指向集合或向量中的对象的指针 - 重要吗?
【发布时间】:2010-10-28 21:25:20
【问题描述】:
刚刚遇到一种情况,我需要将堆分配的指针(指向 B 类)存储在 STL 容器中。拥有私有容器(A 类)的类也创建了 B 的实例。A 类将能够为 A 的客户返回一个指向 B 实例的 const 指针。
现在,这些指针存储在集合还是向量中是否重要?我想有一个集合只是为了验证没有存储重复项,但是由于存储了地址,因此可以存储两个具有相同数据的 B 指针(除非我提供了一个用于数据比较的比较类我假设)。
对这个(相当模糊的)主题有什么想法吗?替代方案的优点/缺点是什么? smart_pointers 需要研究吗?
如果有什么不清楚的地方请问我,谢谢!
【问题讨论】:
标签:
c++
pointers
vector
set
【解决方案1】:
将指针存储在标准容器中没有任何问题——无论是向量、集合、映射还是其他任何东西。您只需要知道谁拥有该内存并确保它被适当地释放。选择容器时,请选择最适合您需求的容器。 vector 非常适合随机访问和附加,但不适合在容器中的其他位置插入。 list 非常好地处理插入,但它没有随机访问。集合确保容器中没有重复项并对其进行排序(尽管如果集合包含指针并且您不提供比较器函数,则排序不是很有用)而映射是一组键值对,所以排序和访问是按键完成的。等等。每个容器都有其优点和缺点,哪种容器最适合特定情况完全取决于该情况。
至于指针,同样,在容器中有指针是可以的。您需要担心的问题是谁拥有内存,因此必须担心释放它。如果有一个明确的对象拥有特定指针指向的内容,那么它可能应该是释放它的那个对象。如果本质上是容器拥有内存,那么你需要确保在容器被销毁之前删除容器中的所有指针。
如果您担心有多个指向相同数据的指针浮动,或者特定内存块没有明确的所有者,那么智能指针是一个很好的解决方案。 Boost 的shared_ptr 可能是一个不错的选择,shared_ptr 将成为 C++0x 的一部分。许多人会建议您应该始终使用共享指针,但会涉及一些开销,并且它是否最适合您的特定应用程序将完全取决于您的应用程序。
最终,您需要了解各种容器类型的优缺点,并确定哪种容器最适合您的工作。如何处理指针管理也是如此。您需要以一种清楚谁拥有特定内存块的方式编写程序,并确保该所有者在适当的时候释放它。共享指针只是其中的一种解决方案(尽管是一个很好的解决方案)。最佳解决方案取决于您的程序的具体情况。
【解决方案2】:
为什么首先会有任何重复?如果 A 类是负责创建 实例的唯一实体,并且它私有地持有容器,这意味着其他人无法对其进行变异,在我看来,不应该有重复的理由。好吧,如果有,在将指针添加到向量之前进行一些检查是否可以补救?
我不知道为什么将指针存储在哪种容器中会很重要。容器并不真正操纵它们的数据,它们只是以不同的方式提供对它们的访问。所以,这取决于你:)
【解决方案3】:
如果需要在 stl 容器中存储指针,请使用 shared_ptr。
现在,这集听起来完全错误。你打算怎么处理这些?
如果您需要添加和删除,然后列出。
如果您需要遍历范围或全部,则使用向量。
如果您需要访问特定的,知道一个键,然后映射。
也看看其他人。一种尺寸并不适合所有人。
【解决方案4】:
我的回答是,您所做的任何决定都必须牢记您的目标。如果您需要集合强制执行的“不允许重复”规则,请使用集合。如果没有,那么您可能想要使用向量或任何容器都可以解决问题。
至于 smart_pointers 是的,它们真的非常有用。应该使用它们吗?我不知道,我再一次不知道你的最终目标是什么,或者你试图用他们解决的问题。
基本上是这样。如果我说“我想用锤子。你怎么看?”你可能会说“好吧,为什么,我知道锤子很适合钉钉子和木头场景,但它们也可以用作伤害人的工具或用作书架。看,等一下,这是什么再来一次?”问题是我还没有,真的说我为什么要用锤子。我没有说我要达到什么目标。
因此,如果您有一个总体目标,那么为什么不让我们知道,那么如果您使用正确的工具来完成这项工作,那将是显而易见的,我们可以为您提供更多帮助。
【解决方案5】:
在我看来,除非您有真正的理由不这样做,否则请坚持使用矢量。与向量相比,集合具有一些运行时开销以及相当大的语义开销。