3

如何std::vector分配对象?看起来好像它只是std::allocator::allocate用来创建一块内存,但从不调用std::allocate::construct. 这是真的?是否std::vector只分配内存而从不将对象构造为内存分配?

如果没有默认构造函数怎么办?对象上没有默认构造函数时如何调用构造函数?如果有多个参数怎么办?

例如,使用此代码没有默认构造函数,并且 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;
}
4

2 回答 2

8

自 C++11 以来,这种情况发生了很大变化。

在 C++03 中,construct只能就地执行复制构造。

但是,请注意,std::vector特别是对象数组,但有不同的大小和容量。也就是说,在包含有用数据的数组部分的末尾之外可以有更多的空元素。

这就是标准库的分配器将“构造”和“内存分配”分开的原因。两者allocator都做,但不是同时做。这允许std::vector分配比它使用的更多的内存。添加新元素时,不一定要分配更多内存;它可以通过调用allocator::construct.

另外,请注意所有添加元素以std::vector 将元素作为参数的 C++03 函数。push_back, , insert, 即使是大小的构造函数也将值作为参数。是的,它是一个默认参数,但它仍然需要一个值作为元素。这个元素被复制到向量中,使用调用分配器的construct方法来获取副本。

在 C++11 中,需要标准容器才能使用该allocator_traits<>::construct函数。这是一个将其参数转发给实际构造的可变参数函数。如果该调用格式正确,则此特征函数将(默认情况下。它可以专门化)调用该allocator::construct方法。如果不是,它将尝试放置new

这允许新emplace功能工作。

但是,是的,标准库容器中包含的对象实际上是构造对象。即使分配器的construct方法没有被调用。

于 2012-04-26T20:56:16.057 回答
0

它依赖于实现,但典型的实现用于std::allocator::allocate分配内存块,然后使用放置 new 通过复制构造函数(或 C++11 中的移动构造函数)构造实例。

当元素被擦除时,它们的析构函数被直接调用来销毁对象,即使底层内存没有被释放。

于 2012-04-26T20:49:28.433 回答