vector<X*>* 与 vector<X>* [关闭]
Posted
技术标签:
【中文标题】vector<X*>* 与 vector<X>* [关闭]【英文标题】:vector<X*>* versus vector<X>* [closed] 【发布时间】:2013-09-25 14:32:51 【问题描述】:什么情况下使用比较好:
vector<X*>* vector = new vector<X>();
代替:
vector<X>* vector = new vector<X>();
还有哪些优点/缺点?
【问题讨论】:
这些都不是特别好的。如果可能,我更喜欢std::vector<X>
,或者如果需要,我更喜欢std::vector<std::unique_ptr<X>>
。
我想说你几乎不想做new vector<...>
...
您可能想在第一个示例中分配new vector<X*>()
,对吧?
我同意@chris 和 Oli 的观点。既然vector
已经动态分配了它的内容,为什么还要动态分配向量本身呢?我想不出任何一种情况。
简单规则:如果你不知道有什么区别,就不要使用。
【参考方案1】:
动态分配向量本身几乎没有充分的理由。除非您正在做一些非常不寻常的事情,否则不要这样做。
在所有对象都具有相同类型的常见情况下,您通常需要一个对象向量vector<X>
。
你会想要一个指针向量,vector<X*>
if
X
是多态基类;和
你想通过vector访问X
不同子类型的对象;和
您不需要容器来为您管理对象生命周期。
如果您希望容器管理异构对象的生命周期,则存储诸如std::unique_ptr
之类的智能指针,或使用Boost pointer container 库之类的东西。
如 cmets 中所述,如果对象不能或不应该被移动,您也可以考虑使用指针向量:向量将随着元素的增长而移动它们的元素,以保持一个连续的数组。在这种情况下,您还应该考虑使用像deque
或list
这样的稳定容器。
【讨论】:
您可能需要vector<X*>
的另一个原因是您不希望您的对象在每个向量重新分配时更改地址(如果其他对象保留指向您正在存储的对象的指针,这一点很重要)。
@MatteoItalia:是的,我想提一下。在这种情况下,最好选择一个稳定的容器(deque
或list
);但也许在某些情况下,额外的间接级别更合适。【参考方案2】:
完全不一样,第一种情况是存储指针,第二种情况是存储值。
当你已经有指针时最好使用指针向量,例如在堆上分配的对象(使用new
)。
在这种情况下,您甚至可以使用std::unique_ptr
的向量。
当您直接拥有对象的值时,最好使用值向量,否则您必须确保对象不会被破坏。
我不明白你为什么要动态分配向量?但正如您对这两种情况所做的那样,这不是问题所在。
【讨论】:
【参考方案3】:首选vector<X>
,除非你有充分的理由不这样做。
vector<X*>
如果向量不拥有它正在存储的对象,或者如果您通过某种您无法控制的机制获取指针,则应使用。如果对象的复制或移动成本很高,它也可以更有效,但首先对其进行基准测试 - vector<X>
将具有更好的引用局部性。它有一个很大的缺点,即销毁向量将不会删除包含的指针,使其容易出错且不安全。使用vector<unique_ptr<X>>
解决最后一个问题。
【讨论】:
【参考方案4】:您永远不会想要指向vector
的指针,只需直接使用vector
并让它处理内存管理。而且您永远不会想要 raw 指针的vector
,而是使用某种智能指针,例如std::shared_ptr
。
【讨论】:
【参考方案5】:原始指针在现代 C++ 中并不流行。尤其是当一个人可以完全不使用间接时。对于您不这样做的情况,可以使用智能指针。首先,我不会new
向量本身(我想我从来没有new
ed 任何std
直接输入)。
您可能想要共享一个向量,那么在某些情况下,有一个间接指向向量的原因,但它看起来像这样:
auto myVec = std::make_shared<std::vector<X>>();
// ^ -- that's an std::shared_ptr<std::vector<X>>
但我想,这不是你的问题。你是在向量的内容之后。可能有一个很好的理由间接指向元素,例如在一些聪明的算法中。但我也建议使用智能指针:
auto myVec = std::make_shared<std::vector<std::shared_ptr<X>>>();
myVec.push_back(std::make_shared<X>(xarg1,xarg2));
myVec.push_back(myVec.back());
在这里您可以看到向量中的单个项目被跟踪了两次。如果您出于某种原因想要这样做(这并不像听起来那么疯狂),请使用间接。
【讨论】:
【参考方案6】:如果您想将向量与动态创建的自定义分配器一起使用,则动态创建向量是唯一的选择。
关于 X* Mike Seymour 给出了一个很好的答案。
【讨论】:
以上是关于vector<X*>* 与 vector<X>* [关闭]的主要内容,如果未能解决你的问题,请参考以下文章