向量push_back多次调用copy_constructor吗? [英] vector push_back calling copy_constructor more than once?

查看:102
本文介绍了向量push_back多次调用copy_constructor吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对向量push_back的行为有点困惑,在下面的代码片段中,我希望复制构造函数仅被调用两次,但是输出表明不是。是这种内部行为的向量内部重组吗?

I am a bit confused with the way vector push_back behaves, with the following snippet I expected the copy constructor to be invoked only twice, but the output suggest otherwise. Is it a vector internal restructuring that results in this behaviour.

输出:


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);


推荐答案

会发生什么:


  1. x 是通过 push_back 插入的。出现一个副本:使用参数初始化新创建的元素。 my_int 被接为零,因为 x 的默认构造函数对此进行了初始化。

  1. x is inserted via push_back. One copy occurs: The newly created element is initialized with the argument. my_int is taken over as zero because xs default constructor initialized it so.

第二个元素是 push_back 'd;由于已达到内部容量,因此引导程序需要重新分配内存。< br>由于没有为 Myint 1 隐式定义移动构造函数,因此选择了复制构造函数;第一个元素被复制到新分配的内存中(它的 my_int 仍为零...因此复制构造函数显示 my_int 再次作为 0 ),然后复制 x 以初始化第二个元素(与步骤1中的第一个一样)。 )。这次 x my_int 设置为1,这就是复制构造函数的输出告诉我们的。

The second element is push_back'd; The vector needs to reallocate the memory since the internal capacity was reached.
As no move constructor is implicitly defined for Myint1 the copy constructor is chosen; The first element is copied into the newly allocated memory (its my_int is still zero... so the copy constructor shows my_int as 0 again) and then x is copied to initialize the second element (as with the first in step 1.). This time x has my_int set to one and that's what the output of the copy constructor tells us.

所以通话总数为三。这可能因一个实现而异,因为初始容量可能不同。但是,最少要有两个调用。

So the total amount of calls is three. This might vary from one implementation to another as the initial capacity might be different. However, two calls are be the minimum.

您可以通过预先保留更多内存来减少副本数量-即,增加矢量容量,从而无需重新分配:

You can reduce the amount of copies by, in advance, reserving more memory - i.e. higher the vectors capacity so the reallocation becomes unnecessary:

myints.reserve(2); // Now two elements can be inserted without reallocation.

此外,在插入时,您还可以删除副本:

Furthermore you can elide the copies when inserting as follows:

myints.emplace_back(0);

此放置一个新元素- emplace_back 是一个可变参数模板,因此可以接受任意数量的参数,

This "emplaces" a new element - emplace_back is a variadic template and can therefore take an arbitrary amount of arguments which it then forwards - without copies or moves - to the elements constructor.

1 因为存在一个用户声明的副本构造函数。

1 Because there is a user-declared copy constructor.

这篇关于向量push_back多次调用copy_constructor吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆