指针向量与值向量之间的差异

Gui*_*ume 0 c++ memory pointers class vector

我听说在C ++中不建议使用指针,但我不明白为什么。

我的问题是我想创建一个类对象向量来管理我的类。

vector<MyClass> vectorOfClass;
Run Code Online (Sandbox Code Playgroud)

自然地,为了获得更好的性能,我应该使用类对象指针的向量吗?

vector<MyClass *> vectorOfClass;
Run Code Online (Sandbox Code Playgroud)

也许可以创建类对象的引用向量?

vector<MyClass &> vectorOfClass;
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:

  • 这些方式有什么区别?
  • 创建类对象向量的最优化方法是什么?

Gui*_*cot 6

也许可以创建类对象的引用向量?

否。引用不是C ++中的对象。因此,您无法创建引用数组或指向引用的指针。但是std::reference_wrapper,您可以使用将引用包装在对象中的。

创建类对象向量的最优化方法是什么?

始终取决于情况。测量,分析并根据您的数据做出决定。

这些方式有什么区别?

它们以不同的方式存储。

值向量在内存中看起来像这样:

+----------------------+
| std::vector<MyClass> |----
+----------------------+   |
                           |
   -------------------------
   |
   v
+-------------+-------------+-------------+-------------+
|   MyClass   |   MyClass   |   MyClass   |   MyClass   |
+-------------+-------------+-------------+-------------+
Run Code Online (Sandbox Code Playgroud)

指针向量如下所示:

+-----------------------+
| std::vector<MyClass*> |---
+-----------------------+  |
                           |
          ------------------
          |
          v
       +-------+-------+-------+-------+
       |  ptr  |  ptr  |  ptr  |  ptr  |
       +-------+-------+-------+-------+
           |       |      |          |
           v       |      v          |
+-------------+    | +-------------+ |
|   MyClass   |    | |   MyClass   | |
+-------------+    | +-------------+ |
                   v                 v
        +-------------+         +-------------+
        |   MyClass   |         |   MyClass   |
        +-------------+         +-------------+
Run Code Online (Sandbox Code Playgroud)

两者都有优点和缺点。

对于值:

  • 优点:连续的内存。没有指针追逐,并且通常非常快地进行迭代。
  • Pro:自动内存管理。Vector将管理其分配的每个值的内存。
  • 缺点:参考无效。调整向量的大小将使对该向量中每个对象的引用无效。
  • 缺点:对于非平凡的对象,调整大小的速度较慢。调整大小涉及到移动对象。对于大型或非平凡的对象,这可能会比较慢。

对于指针:

  • 优点:没有参考无效。对象的地址由您管理。
  • 优点:更快的重新分配,因为这是在周围复制指针而不是在周围移动对象的代价。
  • 缺点:迭代速度慢。对于向量中的每个元素,CPU都将要求内存,并且无法有效使用其缓存。
  • 缺点:您必须使用std::unique_ptr拥有的内存,并且很可能会明确分配每个对象。分配大量不同的对象很慢。

默认选择应为std::vector<MyClass>。到目前为止,这是最简单的方法,适用于大多数情况。通常,当我需要引用那些对象时,我倾向于在向量中使用稳定的索引,只要中间没有删除任何元素即可。