When是在创建类对象的向量时调用的构造函数

When is the constructor called when a vector of class objects is created?

本文关键字:向量 调用 构造函数 对象 创建 When      更新时间:2023-10-16

假设我有一个类Foo。Foo没有默认构造函数。它有一个构造函数Foo(int x, float y)。

Bar是一个容器类。它包含一个vector,其中包含Foo的实例。

Bar::Bar(int numberOfFoos, int x, float y) {
foovector.resize (numberOfFoos);
for(int i = 0; i < numberOfFoos; i++) {
   **read below**
}

在这里,我想调用Foo的构造函数并将参数int x和float y传递给它,Foo的构造函数根据x和y的值做不同的事情。

假设Foo有一个默认构造函数,那么resize向量函数到底是做什么的?它只是简单地调整vector的大小而不调用默认构造函数吗?换句话说,是否为n个类型为Foo的元素保留空间,但它们没有初始化为任何东西?

如果没有呢,就像这个例子一样?

在for循环中,我想用这种方式初始化每个Foo元素:

foovector[i].Foo(int x, float y);

,但我不能以这种方式使用点访问操作符调用构造函数。我甚至不知道这个构造函数是否已经被resize函数调用了

问题是,我怎么做?

关于类的向量的另一个相关问题:

在Foo中有一个保存浮点数的vector。float x参数是它应该容纳的浮点数。Foo的构造函数有一行

arrayofFloats.resize (x);

但这意味着计算机事先不知道Foo的大小。每个foo可以有不同的大小。它不会给向量Foo带来问题吗?如果每个Foo可以有不同的大小,如何声明特定大小的向量?

对不起,我的英语不好,我希望我已经足够清楚了。

谢谢。

请勿使用resize预留空间。相反,使用reserve:

foovector.reserve(n);                          // reserves memory only, no object
                                               // constructions take place
for (std::size_t i = 0; i != n; ++i)
{
    foovector.emplace_back(12 * i, i / 3.0);   // pushes a new Foo(12*i, i/3.0)
}                                              // at the back of the vector

如果我理解正确的话,您希望Bar构造函数在一个向量中构造多个Foo实例,每次都向Foo构造函数提供相同的参数。如果 Foo构造函数的工作方式使Foo对象在构造后都是相同的,你可以使用std::vector::assign(size_type n, const value_type& val),其中value_type在这种情况下是Foo。如果调用foovector.assign( numberOfFoos, Foo(x, y) ),向量将构造一个临时Foo对象,并用该对象的numberOfFoos个副本填充自己。assign()还可以处理您的所有大小调整需求。

但是如果Foo构造函数包含随机行为、静态计数器或其他导致对构造函数的连续调用产生不同对象的东西,那么复制就不是你想要的。

你的另一个问题:

在c++中,每个类型都有固定的大小。(这就是为什么多态性只适用于指针或引用传递语义。)许多类(如std::vector)管理额外的内存,这些内存可以根据需要增加或减少。这一切都是在后台用指针完成的。额外的内存,例如向量所包含的数据,在其他内存位置关闭,不影响实际的对象的大小。vector方法size()resize()reserve()使用托管内存。因此,无论向量中有多少个元素,Foo对象的大小都是相同的。

resize 是否初始化新元素;具体来说,它对临时对象进行值初始化(如果是类类型,则使用默认构造函数),然后使用该构造函数对每个元素进行复制初始化。

如果它没有默认构造函数,或者不能复制初始化,那么你就不能使用resize

然而,你可以使用reserve来预留内存,而不初始化其中的任何对象;然后在该空间中使用push_backinsert元素。在c++ 11中,您还可以使用emplace_back来避免复制元素:

foovector.reserve (numberOfFoos);
for(int i = 0; i < numberOfFoos; i++) {
   foovector.push_back(Foo(42, 1.23));   // C++03, requires copy constructor
   foovector.emplace_back(42, 1.23);     // C++11, doesn't require copy constructor
}

关于你的额外问题:

但这意味着计算机事先不知道Foo

的大小

是的。vector是一个小对象,包含一个指向动态分配内存的指针;它的大小是固定的,不依赖于它分配了多少内存。