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的假设是正确的,你应该可以证实
这也可以通过试验代码来实现。
我做了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的假设是正确的,你应该可以证实 这也可以通过试验代码来实现。