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&lt;X&gt;,或者如果需要,我更喜欢std::vector&lt;std::unique_ptr&lt;X&gt;&gt; 我想说你几乎不想做new vector&lt;...&gt;... 您可能想在第一个示例中分配new vector&lt;X*&gt;(),对吧? 我同意@chris 和 Oli 的观点。既然vector 已经动态分配了它的内容,为什么还要动态分配向量本身呢?我想不出任何一种情况。 简单规则:如果你不知道有什么区别,就不要使用 【参考方案1】:

动态分配向量本身几乎没有充分的理由。除非您正在做一些非常不寻常的事情,否则不要这样做。

在所有对象都具有相同类型的常见情况下,您通常需要一个对象向量vector&lt;X&gt;

你会想要一个指针向量,vector&lt;X*&gt; if

X 是多态基类;和 你想通过vector访问X不同子类型的对象;和 您不需要容器来为您管理对象生命周期。

如果您希望容器管理异构对象的生命周期,则存储诸如std::unique_ptr 之类的智能指针,或使用Boost pointer container 库之类的东西。

如 cmets 中所述,如果对象不能或不应该被移动,您也可以考虑使用指针向量:向量将随着元素的增长而移动它们的元素,以保持一个连续的数组。在这种情况下,您还应该考虑使用像dequelist 这样的稳定​​容器。

【讨论】:

您可能需要vector&lt;X*&gt; 的另一个原因是您不希望您的对象在每个向量重新分配时更改地址(如果其他对象保留指向您正在存储的对象的指针,这一点很重要)。 @MatteoItalia:是的,我想提一下。在这种情况下,最好选择一个稳定的容器(dequelist);但也许在某些情况下,额外的间接级别更合适。【参考方案2】:

完全不一样,第一种情况是存储指针,第二种情况是存储值。

当你已经有指针时最好使用指针向量,例如在堆上分配的对象(使用new)。 在这种情况下,您甚至可以使用std::unique_ptr 的向量。

当您直接拥有对象的值时,最好使用值向量,否则您必须确保对象不会被破坏。

我不明白你为什么要动态分配向量?但正如您对这两种情况所做的那样,这不是问题所在。

【讨论】:

【参考方案3】:

首选vector&lt;X&gt;,除非你有充分的理由不这样做。

vector&lt;X*&gt; 如果向量不拥有它正在存储的对象,或者如果您通过某种您无法控制的机制获取指针,则应使用。如果对象的复制或移动成本很高,它也可以更有效,但首先对其进行基准测试 - vector&lt;X&gt; 将具有更好的引用局部性。它有一个很大的缺点,即销毁向量将不会删除包含的指针,使其容易出错且不安全。使用vector&lt;unique_ptr&lt;X&gt;&gt; 解决最后一个问题。

【讨论】:

【参考方案4】:

您永远不会想要指向vector 的指针,只需直接使用vector 并让它处理内存管理。而且您永远不会想要 raw 指针的vector,而是使用某种智能指针,例如std::shared_ptr

【讨论】:

【参考方案5】:

原始指针在现代 C++ 中并不流行。尤其是当一个人可以完全不使用间接时。对于您不这样做的情况,可以使用智能指针。首先,我不会new 向量本身(我想我从来没有newed 任何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>* [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

vector 排序

关于vector的一些简单的使用与操作(正在学习中...)

vector<X*>* 与 vector<X>* [关闭]

Vector (了解)

C++ 动态分配的 std::vector

C++语言中关于vector的初始化问题