简体   繁体   English

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

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

Say I have a class called Foo. 假设我有一个名为Foo的课程。 Foo doesn't have a default constructor. Foo没有默认构造函数。 It has a constructor Foo(int x, float y). 它有一个构造函数Foo(int x,float y)。

Bar is a container class. Bar是一个容器类。 It contains a vector that contains instances of Foo. 它包含一个包含Foo实例的向量。

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

foovector.resize (numberOfFoos);
for(int i = 0; i < numberOfFoos; i++) {
   **read below**
}

at this point, I want to call the constructor of Foo and pass to it the parameters int x and float y. 在这一点上,我想调用Foo的构造函数并将参数int x和float y传递给它。 The constructor of Foo does different things depending on the value of x and y. Foo的构造函数根据x和y的值做不同的事情。

Let's say Foo had a default constructor, what exactly does the resize vector function do? 假设Foo有一个默认构造函数,调整大小矢量函数究竟做了什么? Does it simply resize the vector without calling the default constructor? 它是否只是在不调用默认构造函数的情况下调整向量的大小? In other words, is space reserved for n elements of type Foo but they aren't initialized to anything?? 换句话说,是为Foo类型的n个元素保留的空间,但是它们没有被初始化为任何东西?

What if it doesn't have one, like in this case? 如果它没有,如果在这种情况下怎么办?

in the for loop I want to initialize each Foo element in this way: 在for循环中我想以这种方式初始化每个Foo元素:

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

but I can't call the constructor using the dot access operator in this way. 但是我不能以这种方式使用点访问运算符来调用构造函数。 I don't even know at this point if the constructor has already been called by the resize function or not. 我现在甚至都不知道构造函数是否已经被resize函数调用过。

Question is , how can I do it? 问题是 ,我该怎么办?

Another related question about vectors of classes: 关于类向量的另一个相关问题:

In Foo there is a vector that holds floats. 在Foo中有一个包含浮点数的向量。 the float x parameter is the number of floats that it should hold. float x参数是它应该保持的浮点数。 Foo's constructor has a line Foo的构造函数有一条线

arrayofFloats.resize (x);

But that means that the computer doesn't know beforehand the size of Foo. 但这意味着计算机事先并不知道Foo的大小。 And each foo can have different size. 每个foo可以有不同的大小。 Wouldn't it cause problems for a vector of Foo's? 它不会导致Foo的矢量问题吗? How can a vector of specific size be declared if each Foo can have different size? 如果每个Foo可以有不同的大小,如何声明特定大小的向量?

Sorry for bad english, I hope it has been clear enough. 抱歉英语不好,我希望它已经足够清楚了。

Thank you. 谢谢。

Don't use resize to reserve space. 不要使用resize来保留空间。 Instead, use reserve : 相反,使用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

If I understand this right, you want the Bar constructor to construct numerous instances of Foo within a vector with the same arguments to the Foo constructor each time. 如果我理解这一点,你希望Bar构造函数在向量中构造许多Foo实例,每次都有与Foo构造函数相同的参数。 IF the Foo constructor works in such a way that the Foo objects will all be identical after construction, you can use std::vector::assign(size_type n, const value_type& val) , where value_type in this case is Foo. 如果 Foo构造函数以这样的方式工作,即Foo对象在构造之后都是相同的,则可以使用std::vector::assign(size_type n, const value_type& val) ,其中value_type在这种情况下是Foo。 If you call foovector.assign( numberOfFoos, Foo(x, y) ) , the vector will construct one temporary Foo object and fill itself with numberOfFoos copies of that object. 如果调用foovector.assign( numberOfFoos, Foo(x, y) ) ,向量将构造一个临时Foo对象,并用该对象的numberOfFoos副本填充自身。 assign() also handles all your resizing needs. assign()还可以处理所有调整大小的需求。

But if the Foo constructor involves random behavior, static counters, or something else that causes successive calls to the constructor to result in different objects, copying is not what you want. 但是,如果Foo构造函数涉及随机行为,静态计数器或其他导致连续调用构造函数导致不同对象的内容,则复制不是您想要的。

Your other question: 你的另一个问题:

In C++, every type has a fixed size. 在C ++中,每种类型都有固定的大小。 (This is why polymorphism only works with pointers or pass-by-reference semantics.) Many classes, such as std::vector , manage additional memory which can grow or shrink as needed. (这就是多态性仅适用于指针或传递引用语义的原因。)许多类(如std::vector )管理可根据需要增长或缩小的额外内存。 This is all done behind the scenes with pointers. 这一切都是在幕后用指针完成的。 Additional memory, such as the data contained by a vector, is off in some other memory location and does not affect the actual size of the object. 附加内存(例如矢量包含的数据)在某些其他内存位置关闭,不会影响对象的实际大小。 The vector methods size() , resize() , and reserve() work with that managed memory. vector方法size()resize()reserve()与该托管内存一起使用。 So a Foo object is the same size no matter how many items are in its vector. 因此,无论其向量中有多少项,Foo对象的大小都相同。

resize does initialise the new elements; resize 初始化新元素; specifically, it value-initialises a temporary object (using the default constructor, if it's a class type), then copy-initialises each element using that. 具体来说,它初始化一个临时对象(使用默认构造函数,如果它是一个类类型),然后使用它复制初始化每个元素。

If it doesn't have a default constructor, or can't be copy-initialised, then you can't use resize . 如果它没有默认构造函数,或者无法进行复制初始化,则无法使用resize

However, you can use reserve to reserve memory without initialising any objects in it; 但是,您可以使用reserve来保留内存而不初始化其中的任何对象; and then use push_back or insert elements into that space. 然后使用push_backinsert元素到该空间。 In C++11, you can also use emplace_back to avoid the need to copy elements: 在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
}

Regarding your extra question: 关于你的额外问题:

But that means that the computer doesn't know beforehand the size of Foo 但这意味着计算机事先并不知道Foo的大小

Yes it does. 是的,它确实。 A vector is a small object containing a pointer to some dynamically allocated memory; 向量是一个小对象,包含指向某些动态分配的内存的指针; its size is fixed, and does not depend on how much memory it allocates. 它的大小是固定的,并不依赖于它分配的内存量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用类对象创建向量时未调用类构造器 - Class Constructor is not getting called when creating a vector with class objects 为什么在创建向量时,类A的构造函数和析构函数被调用一次<A>?</a> - Why are the constructor and desctructor of class A called once when creating a vector<A>? 返回std :: vector时未调用复制构造函数 - copy constructor not called when returning a std::vector 将对象作为参数传递时会调用构造函数吗? - Is a constructor called when passing objects as an argument? 什么时候对使用“new”创建的临时对象调用“delete”? - When is 'delete' called on temporary objects created with `new`? class 构造函数中的向量时出现运行时错误? - Runtime error when vector in class constructor? 在以下向量中添加新元素时使用非默认构造函数 <class> 对象 - Using non-default constructor when adding a new element in a vector of <class> objects 什么时候使用指针调用C ++类构造函数? - When is C++ Class Constructor called with pointer? 分配该类的两个对象时,为什么调用构造函数? - Why is my constructor being called when I assign two objects of that class? 为什么只有在向量中已有元素时才调用移动构造函数? - Why is the move constructor only called when there is already an element in the vector?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM