C++:在向量中插入什么 - 指针或引用,矢量何时复制它的元素?

C++: What to insert in vectors - pointers or references, when does a vector copy it's elements?

本文关键字:何时 复制 元素 引用 向量 插入 指针 什么 C++      更新时间:2023-10-16

假设我有一个复杂的对象,比如包含大量成员的结构体,并且我想将它们存储在一个vector中。

现在vector::push_back(…)在按引用调用(而不是按值调用)上工作,因此在第一时间不会复制传递的对象。但之后呢?vector内部存储指针还是直接引用?当vector需要展开时,是复制所包含的元素本身还是复制它们的地址?

这最终导致了一个问题,如果——对于大对象——对象本身应该存储在vector中,或者应该存储在指向这些对象的指针中。有没有最好的做法呢?

std::vector::push_back保存复制对象。

如果需要通过避免复制来提高性能,那么可以使用指针向量。

std::vector<BigObject*> objects; //manage memory yourself

或者您可以使用某种智能指针,从而避免自己管理内存。例如,如果编译器支持std::unique_ptr,则可以使用它:

std::vector<std::unique_ptr<BigObject>> objects;

如果您使用指针(或智能指针),那么复制仍然存在,但这次,复制是针对指针(或智能指针)完成的,这要便宜得多。

摘自@Loki的评论:

或者你可以使用boost::ptr_vector<>,它被设计为保存指针,并在访问时返回引用,从而使使用标准算法变得容易,因为它们都期望对象。

vector::push_back(...)工作于按引用调用(而不是按值调用),因此在第一时间传递的对象不会被复制

vector::push_back()存储被添加对象的副本。

vector内部存储指针还是直接引用?

vector内部如何存储元素是一个实现细节,但复杂性和行为需求几乎没有留下变化的空间。Vector像数组一样将元素存储在连续的内存位置中。

当vector需要展开时,是复制所包含的元素本身还是复制其地址?

当vector展开时,它需要将所有对象复制到一个新的连续内存中,这也是一个实现细节。如果元素是指针,则复制指针本身。

对象本身应该存储在vector或指向这些对象的指针中。有没有最好的做法呢?

如果你的对象更大,你不想把它们放在vector中,那么你可以在vector中存储指向它们的指针,但不要在vector中存储原始指针,根据你的要求使用合适的智能指针。它确保了完美的RAII,您不需要显式地为内存管理而烦恼。

实际上,如果你在vector上迭代的次数多于向它添加对象的次数,那么通过添加对象将大大优于指针,因为它们在内存中是连续的。

但是,如果你对vector对象进行更多的添加和删除操作,而不是迭代操作,那么指针将更有效。