[英]How does std::vector allocate objects?
How does std::vector
allocate objects? std::vector
如何分配对象? It would seem as if it just uses std::allocator::allocate
to create a block of memory, but then never calls std::allocate::construct
. 看起来好像它只是使用
std::allocator::allocate
来创建一个内存块,但是从不调用std::allocate::construct
。 Is this true? 这是真的? Does
std::vector
only allocate memory and never construct the objects as memory allocation? std::vector
是否只分配内存而从不构造对象作为内存分配?
What if there is no default constructor? 如果没有默认构造函数怎么办? How is the constructor called when there is no default constructor on the object?
当对象上没有默认构造函数时,构造函数是如何调用的? What if there is more than one parameter?
如果有多个参数怎么办?
For example, with this code there is no default constructor and std::allocator allows it. 例如,使用此代码没有默认构造函数,std :: allocator允许它。
#include <vector>
using namespace std;
class A{
protected:
int m;
public:
explicit A(int a) : m(a) { }
};
int main(){
vector<A> test;
return 0;
}
This has rather changed since C++11. 自C ++ 11以来,这已经发生了很大变化。
In C++03, construct
could only perform copy-construction in-place. 在C ++ 03中,
construct
只能就地执行复制构造。
However, note that std::vector
in particular is an array of objects, but there is a distinct size and capacity. 但是,请注意
std::vector
特别是一个对象数组,但是有一个不同的大小和容量。 That is, there can be more empty elements beyond the end of the part of the array that contains useful data. 也就是说,在包含有用数据的数组部分的末尾之外可以有更多的空元素。
That is why the standard library's allocator has a separation between "construction" and "memory allocation." 这就是标准库的分配器在“构造”和“内存分配”之间存在分离的原因。 The
allocator
does do both, but not at the same time . allocator
确实做到了这allocator
,但不能同时做到。 This allows std::vector
to allocate more memory than it uses. 这允许
std::vector
分配比它使用的内存更多的内存。 When you add new elements, it doesn't necessarily have to allocate more memory; 添加新元素时,不一定要分配更多内存; it can just use the spare memory it has left over via a call to
allocator::construct
. 它可以通过调用
allocator::construct
来使用它留下的备用内存。
Also, note that all of the C++03 functions that add elements to std::vector
take an element as a parameter. 此外,请注意所有这些添加元素添加到C ++ 03功能
std::vector
取的元素作为参数。 push_back
, insert
, even the sized constructor takes as a value as an argument . push_back
, insert
,甚至是大小的构造函数都将值作为参数 。 Yes, it's a default parameter, but it still takes a value as an element. 是的,它是一个默认参数,但它仍然需要一个值作为元素。 This element is copied into the vector, using a call to the allocator's
construct
method which takes a copy. 使用对分配器的
construct
方法的调用将该元素复制到向量中,该construct
方法获取副本。
In C++11, standard containers are required to use the allocator_traits<>::construct
function. 在C ++ 11中,标准容器需要使用
allocator_traits<>::construct
函数。 This is a varadic function that forwards its parameters to the actual construct. 这是一个将其参数转发给实际构造的varadic函数。 This traits function will (by default. It can be specialized) call the
allocator::construct
method if that call is well-formed. 这个traits函数将(默认情况下可以是专用的)调用
allocator::construct
方法,如果该调用格式正确的话。 If it isn't, it will try placement new
. 如果不是,它将尝试放置
new
。
This allows for the new emplace
functions to work. 这允许新的
emplace
功能起作用。
But yes, the objects contained in standard library containers are in fact constructed objects. 但是,标准库容器中包含的对象实际上是构造对象。 Even if the allocator's
construct
method is not called. 即使没有调用allocator的
construct
方法。
It's implementation dependent, but a typical implementation uses std::allocator::allocate
to allocate the block of memory, and then uses the placement new to construct, via the copy constructor (or move constructor in C++11), the instances. 它依赖于实现,但是典型的实现使用
std::allocator::allocate
来分配内存块,然后使用placement new来构造,通过复制构造函数(或在C ++ 11中移动构造函数)来构造实例。
When elements are erased, their destructors are directly invoked to destroy the objects, even if the underlying memory isn't released. 删除元素时,即使未释放底层内存,也会直接调用它们的析构函数来销毁对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.