6
vector<X> v;
X x;
v.push_back(x); v.push_back(x); v.push_back(x);

为什么这段代码调用一个类的复制构造函数X 6 次?(使用 g++ 4.7.2 STL)

拜托,我想确切地知道这个特定的 STL 在引擎盖下会发生什么。

4

4 回答 4

12

当您插入xpush_back(),最终会重新分配内存以为新元素腾出空间。然后必须使用复制构造函数复制已插入的成员X(const X&)

如果你插入

v.reserve(3);

至少在前三个push_back()s 中阻止了重新分配,因此,将只有三个调用X(const X&)

于 2012-11-15T10:57:09.430 回答
1

这就是发生的事情:

在第一次 push_back 之前,向量的容量(适合其分配的空间的元素数)为 0。因此,当您执行第一次 push_back 时,它为 1 个项目分配空间并调用复制构造函数(第一次调用) .

所以现在容量是一个,你告诉它添加另一个项目。所以它必须分配更多的空间,在这种情况下,空间用于多一个项目并将原始项目复制到新空间(第二次调用)。第二个 push_back 再次调用复制构造函数(第三次调用)。

现在您的容量为 2,并告诉它添加另一个项目。所以它必须分配更多空间并将项目复制到新空间(第 4 次和第 5 次调用)。然后第三个 push_back 再次调用复制构造函数(第 6 次调用)。

正如其他人指出的那样,您可以使用reserve,它将预先分配空间,避免重新分配的需要,从而调用复制构造函数。

于 2012-11-15T11:24:22.463 回答
1

正确的答案是std::vector使用加倍数组实现(参见:http ://en.wikipedia.org/wiki/Dynamic_array ),它调用的复制构造函数大约2 * N是复制构造函数的倍数。

例如,因为N = 100,000它调用了复制构造函数231,071次。正如已经指出的那样,可以通过调用来减少重新分配的次数 to v.reserve()

于 2012-11-15T11:14:45.203 回答
1

您可以事先使用向量保留在向量中创建空间,以加快向向量添加元素并阻止这种情况发生。

于 2012-11-15T10:59:37.027 回答