为什么std :: vector的元素不需要默认构造函数?

时间:2010-03-04 05:02:19

标签: c++ vector default-constructor

如何编写自己的数组类,不需要 元素的默认构造函数?现在,当我执行new []来分配空间时,我需要一个默认的构造函数。

std :: vector没有。

他们如何做到这一点?

4 个答案:

答案 0 :(得分:29)

std::vector不需要默认构造函数,因为它从不使用它。每次需要构造一个元素时,它都是通过使用复制构造函数来完成的,因为每次都有复制的东西:现有的vector元素或你自己提供的元素,用于复制方法的参数(明确地或隐含地,依赖于默认参数

您可以以完全相同的方式编写类似的类:每次需要在数组中构造新元素时,都需要用户提供复制元素。在这种情况下,构建该原始元素将成为用户的责任。

每当看起来好像std::vector“需要”你的默认构造函数时,它只是意味着某个地方依赖于某些vector方法的默认参数,即它是< em>你谁试图默认构造一个元素,而不是矢量。另外,向量本身永远不会尝试默认构造元素。

为了避免内存分配期间的默认构造函数要求,标准库分配 raw未初始化内存块,然后立即复制构造该原始内存块中的新元素({{1} } 无法做到)。此功能已在new[]类中封装。您也可以在代码中使用std::allocator,这意味着您也可以立即使用“魔法”。

注意:以上内容适用于C ++之前的C ++语言规范版本。 C ++ 11改变了很多东西。这些更改确实会创建std::allocator内部可以使用默认构造函数的情况。

同样值得注意的是,即使最初的C ++ 98规范允许实现使用函数重载而不是默认参数来实现标准库接口。这意味着正式地可以使用std::vector的有效C ++ 98实现,该实现在内部使用默认构造函数

答案 1 :(得分:11)

如果你以一种需要默认构造函数的方式使用它,那么

std::vector只需要元素有一个默认的构造函数。因此,此代码(从已删除的答案中窃取)将无法编译,因为X没有默认的ctor:

#include <vector>

struct X
{
  X(int) {}
};

int main(void)
{
  std::vector<X> x(1); // vector of length 1, second argument defaults to X() !!
  return 0;
}

但如果你这样写main

int main(void)
{
  std::vector<X> x; // make empty vector
  x.push_back(X(1));
  return 0;
}

然后它工作正常。

答案 2 :(得分:7)

您可以分配一个字节块,然后使用placement new通过复制构造函数(当然不是默认构造函数)创建T(您的参数类型)的新实例,当新项目被推送到矢量回来了。这将不允许制作“N默认初始化Ts的向量”(std :: vector可以制作 - 这就是为什么 需要T为此目的使用默认构造函数),但是你可以让向量开始变空并且可以将Ts推到它们上面。

答案 3 :(得分:0)

对我来说std::vector要求我的类使用默认构造函数(例如T),因为我正在调用resize()的{​​{1}}方法,尽管我只是在调用缩小向量但从不增长的方法。