我对矢量push_back行为的方式有点困惑,使用下面的代码片段我预计复制构造函数只能被调用两次,但输出建议不然.是矢量内部重组导致这种行为.
输出:
Run Code Online (Sandbox Code Playgroud)Inside default Inside copy with my_int = 0 Inside copy with my_int = 0 Inside copy with my_int = 1
class Myint
{
private:
int my_int;
public:
Myint() : my_int(0)
{
cout << "Inside default " << endl;
}
Myint(const Myint& x) : my_int(x.my_int)
{
cout << "Inside copy with my_int = " << x.my_int << endl;
}
void set(const int &x)
{
my_int = x;
}
}
vector<Myint> myints;
Myint x;
myints.push_back(x);
x.set(1);
myints.push_back(x);
Run Code Online (Sandbox Code Playgroud)
Col*_*mbo 11
怎么了:
x通过插入push_back.发生一个副本:使用参数初始化新创建的元素.my_int被取为零,因为xs默认构造函数初始化它.
第二个元素是push_back'd; 由于达到了内部容量,向量需要重新分配内存.
由于没有为Myint1隐式定义移动构造函数,因此选择了复制构造函数; 第一元件被复制到新分配的存储器(其my_int仍然是零...这样的拷贝构造示出了my_int作为0再次),然后x被复制到初始化所述第二元件(与第一在步骤1).这时候x已经my_int设置为一个,这就是拷贝构造函数的输出告诉我们.
所以通话总数是三.这可能因实现而异,因为初始容量可能不同.但是,两次通话是最小的.
您可以提前预留更多内存来减少副本数量 - 即更高的向量容量,因此重新分配变得不必要:
myints.reserve(2); // Now two elements can be inserted without reallocation.
Run Code Online (Sandbox Code Playgroud)
此外,您可以在插入时删除副本,如下所示:
myints.emplace_back(0);
Run Code Online (Sandbox Code Playgroud)
这个"赋予"一个新元素 - emplace_back是一个可变参数模板,因此可以接受任意数量的参数,然后将其转发 - 无需复制或移动 - 到元素构造函数.
1因为有一个用户声明的复制构造函数.
| 归档时间: |
|
| 查看次数: |
1225 次 |
| 最近记录: |