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

2021-12-21 00:00:00 vector c++ default-constructor

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

And how can I write my own array class to not need a default constructor for its elements? Right now, when I do the new [] to allocate space, I need a default constructor.

std::vector 没有.

std::vector does not.

他们是如何施展这种魔法的?

How do they do this magic?

推荐答案

std::vector 不需要默认构造函数,因为它从不使用它.每次它需要构造一个元素时,它都会使用复制构造函数来完成,因为每次它都有要复制的东西:现有的向量元素或您自己提供的用于通过方法参数复制的元素(显式或隐式,依赖于默认参数)

std::vector doesn't need the default constructor because it never uses it. Every time it needs to construct an element, it does it by using the copy constructor, because every time it has something to copy: either existing vector element or an element you yourself supplied for copying through a method's parameter (explicitly or implicitly, by relying on a default argument)

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

You can write a class like that in exactly the same way: every time you need to construct a new element in your array, require the user to supply an element for copying. In this case constructing that original element becomes user's responsibility.

每次看起来好像std::vector需要"你的默认构造函数时,它只是意味着你在某处依赖了某些vector的默认参数code>s 方法,即是 you 试图默认构造一个元素,而不是向量.同样,向量本身永远不会尝试默认构造元素.

Every time it appears as if std::vector "requires" a default constructor from you, it simply means that somewhere you relied on a default argument of some of the vectors methods, i.e. it was you who tried to default-construct an element, not the vector. The vector itself, again, will never try to default-construct elements.

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

In order to avoid the default constructor requirement during memory allocation, standard library allocates raw uninitialized memory block and then immediately copy-constructs new elements in that raw memory block (which is something new[] cannot do). This functionality is incapsulated in std::allocator class. You can use std::allocator in your code as well, meaning that the "magic" is immediately available to you too.

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

Note: The above applies to pre-C++11 version of C++ language specification. C++11 changed a lot of things. And these changes do create situations in which std::vector can use default constructors internally.

另外值得注意的是,即使是原始的 C++98 规范也允许实现使用函数重载而不是默认参数来实现标准库接口.这意味着在形式上可以有一个有效的 std::vector 的 C++98 实现,它在内部使用默认构造函数.

Also it might be worth noting that even the original C++98 specification allowed implementations to use function overloading instead of default arguments in order to implement the standard library interface. This means that formally it is possible to have a valid C++98 implementation of std::vector that uses default constructors internally.

相关文章