在c++中调整vector大小时调用一次类构造函数

Class constructor called once while resizing vector in C++

本文关键字:一次 构造函数 调用 c++ 调整 vector 小时      更新时间:2023-10-16

我正在尝试学习c++ STL中的向量…

我有一个类temp作为:

class temp
{
private :
    int a;
public :
    //temp() {}
    temp(int a)
    {
        std::cout<<"ctor called"<<std::endl;
        this->a=a;
    }
    void setA(int a)
    {
        this->a=a;
    }
    int getA()
    {
        return a;
    }
};

现在,在main中,我写:

int main() {
    vector<temp> v;
    v.resize(7,temp(5));
    for(int i=0;i<7;i++) {
        v[i].setA(i);
    }
    for(int i=0;i<7;i++) {
        cout<<v[i].getA()<<"t";
    }
}
我得到的输出是
ctor called
0 1 2 3 4 5 6 

我想知道为什么构造函数只调用一次,甚至在创建7个不同的对象类temp

因为vector的元素是通过复制形参来初始化的。您所传递的参数的创建是代码中唯一调用您所编写的函数的时候。这里描述了您正在调用的std::vector中的tor,您正在调用的是版本(2)。

将复制器添加到您的类中,看看发生了什么:

temp(const temp& t)
{
    std::cout<<"copy-ctor called"<<std::endl;
    this->a = t->a;
}

在您的代码中,编译器为您生成了一个复制因子,但显然没有调试输出,因此您无法看到它

构造函数正在为您用temp(5)创建的临时对象调用。vector的所有元素都是通过复制该对象来构造的。这当然会使用复制/移动构造函数。

基本上,您调用的vector的构造函数只要求该向量的元素类型为CopyInsertable。这意味着以下内容必须是正确的:

allocator_traits<A>::construct(a, p, v);

其中A是分配器类型,a是分配器对象,p是指向已分配内存的指针,v是要构造的对象。这实际上是使用placement-new来构造vector的一个元素,将v的值传递给它的构造函数。在本例中,v是传递给构造函数的第二个参数,因此它调用复制/移动构造函数。