C++ 创建类对象的向量时,何时调用构造函数?

C++ 创建类对象的向量时,何时调用构造函数?,c++,class,vector,C++,Class,Vector,假设我有一门课叫Foo。Foo没有默认的构造函数。它有一个构造函数Foo(intx,float y) Bar是一个容器类。它包含一个包含Foo实例的向量 Bar::Bar(int numberOfFoos, int x, float y) { foovector.resize (numberOfFoos); for(int i = 0; i < numberOfFoos; i++) { **read below** } 但是我不能以这种方式使用点访问操作符调用构造函数。此时我甚至

假设我有一门课叫Foo。Foo没有默认的构造函数。它有一个构造函数Foo(intx,float y)

Bar是一个容器类。它包含一个包含Foo实例的向量

Bar::Bar(int numberOfFoos, int x, float y) {

foovector.resize (numberOfFoos);
for(int i = 0; i < numberOfFoos; i++) {
   **read below**
}
但是我不能以这种方式使用点访问操作符调用构造函数。此时我甚至不知道resize函数是否已经调用了构造函数

问题是,我该怎么做

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

在Foo中,有一个向量包含浮点数。float x参数是它应该保持的浮点数。Foo的构造函数有一行

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

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


谢谢。

不要使用
调整大小
来保留空间。相反,请使用
保留

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
resize
初始化新元素;具体来说,它使用value初始化一个临时对象(如果它是类类型,则使用默认构造函数),然后使用copy初始化每个元素


如果它没有默认构造函数,或者无法进行复制初始化,则不能使用
调整大小

但是,您可以使用
reserve
来保留内存,而无需初始化内存中的任何对象;然后使用
push_back
insert
元素插入该空间。在C++11中,还可以使用
emplace\u 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
}
foovector.reserve(numberofoos);
for(int i=0;i
关于你的额外问题:

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


是的。向量是一个小对象,包含指向某个动态分配内存的指针;它的大小是固定的,并不取决于它分配了多少内存。

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

但是,如果Foo构造函数涉及随机行为、静态计数器或其他导致对构造函数的连续调用产生不同对象的内容,那么复制就不是您想要的

你的另一个问题:

在C++中,每种类型都有固定的大小。(这就是多态性仅适用于指针或按引用传递语义的原因。)许多类,如
std::vector
,管理可以根据需要增加或减少的额外内存。这一切都是在幕后用指针完成的。附加内存(例如向量包含的数据)在其他一些内存位置处于关闭状态,不会影响实际内存
对象的大小。
vector
方法
size()
resize()
、和
reserve()
都使用该托管内存。因此,无论向量中有多少项,Foo对象的大小都是相同的。

可能重复“如果它没有默认构造函数,或者无法复制初始化,那么就不能使用resize”:我相信在C++11中,它将分别初始化每个元素,而不是复制(在这种情况下,
void resize(size_type n);
有一个单独的重载)实际上,如果使用标准分配器,
T
仍然需要
CopyConstructible
,以便在
resize
需要重新分配时将现有元素复制到新存储中,因此“如果它没有默认构造函数,或者不能进行复制初始化,那么就不能使用resize”在大多数情况下是正确的(如果您使用stanard分配器),但是“它值初始化一个临时对象(如果它是类类型,则使用默认构造函数),然后使用该值复制初始化每个元素。“绝对不是:新元素是单独初始化的值。现有元素被移动到新位置,而不是复制,因此它需要是可移动的。对于example@JonathanWakely我想我正在读一本旧的草稿(n3242),我的说“要求:
T
可复制插入
*此
”……是否在最终版本中更新?我在某个地方读到,在重新分配期间移动存在异常安全问题。@JonathanWakely我正在读
(预处理后)它使用
std::\uuuuuuu未初始化\uu move\uu if\uNoExcept\uA
,所以它大概只调用
noexcept
移动构造函数,否则使用复制构造函数?
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
}