C++ 入门练习 13.13,关于构造函数

the c++ primer exercise 13.13, about the constructor

我做了c++ primer的练习13.13,这是我的代码

#include <iostream>
#include <vector>

using namespace std;

struct X{
X(){cout<<"X()"<<endl;}
X(const X&){cout<<"X(const X&)"<<endl;}
X& operator=(const X&){
    cout<<"X& operator=(const X&)"<<endl;
    return *this;
}
~X(){cout<<"~X()"<<endl;}
};

void foo(const X& cx, X bx){
vector<X> v;
v.push_back(cx);
v.push_back(bx);
}

int main(){
X* x1=new X;
X x2;
x2=*x1;
foo(*x1, x2);
delete x1;
return 0;
}

并且我得到了四次 "X(const X&)" 的输出,我猜前三个来自传递 x2、push_back(cx) 和 push_back(bx)。但是为什么会有第四个"X(const X&)?

可能当第二个元素被添加到向量时(v.push_back(bx);),向量底层存储的大小调整完成,向量中已有的单个元素被复制到新存储。

在第二个 push_back() 调用周围添加以下内容:

cout << "about to do push_back(bx)" << endl;
v.push_back(bx);
cout << "done push_back(bx)" << endl;

push_back的实现方式有关

其中一个副本是由于按值将 bx 传递给 foo。 将该参数设为引用,副本数减一

其余似乎都是由于 push_back。 我在 http://www.tutorialspoint.com/compile_cpp_online.php 试过你的代码 每 push_back 之前和之后都有额外的打印输出。 我还将总共 10 个元素推到矢量上。 第二次调用 push_back 导致复制构造函数被调用两次, 第三次调用导致它被调用三次, 第五次呼叫引起了五次, 第九次呼叫引起了九次。 所有其他对 push_back 的调用导致复制构造函数被调用 只有一次。

但是当我在第一次调用 push_back 之前执行 v.reserve(20) 时, 每次调用 push_back 都会导致调用一次复制构造函数。 当我将 20 更改为 8 时,第九个 push_back 导致 九次调用复制构造函数,所有其他调用只产生一次调用。

我得出结论,额外的复制构造函数调用与 vector 必须做的维护(复制现有元素) 当它在没有 "reserved" 它需要的 space 的情况下生长时。

所以Michael Burr的假设是正确的,你应该可以证实 这也可以通过试验代码来实现。