如何编写自己的数组类,不需要 元素的默认构造函数?现在,当我执行new []来分配空间时,我需要一个默认的构造函数。
std :: vector没有。
他们如何做到这一点?
答案 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}}方法,尽管我只是在调用缩小向量但从不增长的方法。