向量 <Class*> 和向量 <Class> 有啥区别?

Posted

技术标签:

【中文标题】向量 <Class*> 和向量 <Class> 有啥区别?【英文标题】:What is the difference between vector <Class*> and vector <Class>?向量 <Class*> 和向量 <Class> 有什么区别? 【发布时间】:2016-02-18 00:54:00 【问题描述】:

std::vector&lt;Class*&gt;std::vector&lt;Class&gt; 有什么区别? 另外,在效率和避免错误方面,哪一个更好?

【问题讨论】:

Why should I use a pointer rather than the object itself?的可能重复 首选std::vector&lt;std::unique_ptr&lt;Class&gt;&gt; 而不是std::vector&lt;Class*&gt; @JonathanPotter 仅当它实际拥有指针时... 【参考方案1】:

vector&lt;Class*&gt; 存储指向对象的指针列表,对象本身必须单独分配,因为它们是指针,您可以使用多态行为,如下所示:

vector<Foo*> list;
list.push_back( new Bar() ); // class Bar : Foo
list.push_back( somePointerToFoo );
list[0]->someVirtualMethod();

请注意,使用这种方法,您必须在创建对象时手动delete 对象。可能就这么简单:

for(Foo* f : list) delete f;

...但是如果您的向量存储从您正在聚合的多个来源收集的指针,那么您需要确定列表是否“拥有”指针并酌情删除对象。

vector&lt;Class&gt; 将实际的类值(其字段)内联存储在向量本身中,这意味着操作通常涉及复制所有值,这可能是也可能不是预期的行为。你总是可以创建指向这些元素的指针,但是你进入了危险的领域:

vector<Foo> list;
list.push_back( Foo() ); // construct an instance of Foo, which might be copied up to 3 times in this single operation, depending on how smart the compiler+library is
list.push_back( *somePointerToFoo ); // this will dereference and copy this instance of Foo
list[0].someVirtualMethod(); // will not be a vtable call

list.push_back( Bar() ); // forbidden, Bar does not fit into Foo

【讨论】:

我建议添加关于释放对象的乐趣的评论。【参考方案2】:

vector&lt;Class*&gt;vector&lt;Class&gt;有什么区别

vector&lt;Class&gt; 存储对象,而vector&lt;Class*&gt; 存储指向对象的指针。当你将一个对象推入第一种向量时,它会被复制;第二个向量存储指针,但对象保持原位。

另外,在效率和避免错误方面,哪一个更好?

让我们从避免错误开始:如果可能,请使用vector&lt;Class&gt;,因为类分配的任何资源都将由vector自动管理。如果vector&lt;*Class&gt; 持有原始对象,您将负责在完成后调用delete

由于object slicing,这可能并非在所有情况下都可行,因此该解决方案并不通用。

就效率而言,vector&lt;*Class&gt; 可以让您避免复制,因此理论上它可能更有效。即使在这种情况下,您也应该更喜欢智能指针,例如 std::shared_ptr&lt;T&gt;std::unique_ptr&lt;T&gt;,而不是内置指针,因为智能指针将帮助您自动化资源管理。

【讨论】:

还有一个问题。这是删除指向对象的指针的正确方法吗? for (size_t i=0; i @Drako 是的,这将是正确的方法。调用clear() 也是一个好主意,因为它可以帮助您避免错误地访问已删除的指针。 在不控制包含对象的生命周期的情况下,可以使用原始指针。 指针可能更有效,但由于现在无法预测对象在内存中的位置,如果对象很小并且用于高速计算,它可能会变成死机.【参考方案3】:

嗯,std::vector&lt;T&gt;Ts 的可动态调整大小的数组。

如果TClass*,它存储指向Class的指针,如果是Class,那么是Class类型的对象。

一般来说,您根本不应该使用原始指针,至少不应该用于拥有指针。查看智能指针。

如果你真的想存储多态类Class或派生类的对象,你必须使用指针,或者某种多态容器。

关于效率,这取决于Class-objects 移动的难易程度、它们的大小以及移动的频率。 换句话说,魔鬼在细节中,而你没有提供这些细节。

【讨论】:

以上是关于向量 <Class*> 和向量 <Class> 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

从两个向量中删除公共实体?

预测$class 中的错误:$ 运算符对原子向量无效

C++ 在类构造函数中填充向量

如何在函数中访问向量的不同成员

转换为唯一基类指针向量

无法在 C++ 中创建结构向量