std::vector 在 push_back 期间多次调用析构函数?
我将对象类tipo 推送到向量,当我推送第一个时,构造函数被调用(它应该被调用)并且析构函数被立即调用(我认为这不应该发生).然后当我推送下一个对象时,构造函数被调用一次,析构函数被调用两次,然后在第三次调用三次,依此类推.
I'm pushing objects class tipo to a vector, when I push the first one the constructor get's called (as it should) and the destructor is called immediatelly (which I don't think should happen). Then when I push the next object the constructor is called once and the destructor is called twice, then on the third three times and so on.
似乎每次我向向量推送内容时都会多次调用析构函数.
It seems that the destructor is called more times every time I push something to the vector.
这是我的课:
class Item
{
protected:
...
public:
Item();
Item(char * no, int hit, int ve, char * pathTilesheet, int an, int al, bool inv, bool vol, bool fan, int mh = NULL);
~Item();
};
Item::Item(char *no, int hi, int ve, char *pathTilesheet, int an, int al, bool inv, bool vol, bool fan, int mh){
// CARGAR SDL
tileSheet = load_image(pathTilesheet);
tileSheetEspejo = flip_surface(tileSheet, FLIP_HORIZONTAL);
}
这是正在发生的事情:
std::vector<Item> vecItems;
vecItems.push_back(Item("life",4,0,"assets/imagenes/hp.png", 8, 8, false, false, false));
// HERE THE CONSTRUCTOR AND THE DESTRUCTOR ARE CALLED
vecItems.push_back(Item("lifeXL",8,0,"assets/imagenes/hp-xl.png", 16, 16, false, false, false));
// HERE THE CONSTRUCTOR IS CALLED ONCE AND THE DESTRUCTOR TWICE
vecItems.push_back(Item("blast 1",-4,14,"assets/imagenes/bola.png", 8, 8, false, true, false));
// HERE THE CONSTRUCTOR IS CALLED ONCE AND THE DESTRUCTOR MULTIPLE TIMES
我做错了吗?为什么会发生这种情况?
Am I doing something wrong? Why could this be happening?
推荐答案
你的每一行代码都会创建一个临时的Item
,将它复制到向量的内存中,然后销毁临时的.这就是为什么你每次看到(至少)一个析构函数调用.
Each line of your code creates a temporary Item
, copies it into the vector's memory, and then destroys the temporary. That's why you see (at least) one destructor call each time.
在 C++11 中,您可以通过使用 emplace_back(args...)
而不是 push_back(Item(args...))
来避免创建和销毁临时文件code>,直接在vector的内存中创建对象.
In C++11, you could avoid creating and destroying the temporary by using emplace_back(args...)
rather than push_back(Item(args...))
, to create the object directly in the vector's memory.
此外,向量有时需要增长,重新分配更大的内存块,以便将其所有元素保留在连续数组中.当它这样做时,每个元素都被移动到新内存中,旧元素被销毁.这就是为什么您有时会看到不止一个析构函数调用.
Additionally, the vector sometimes needs to grow, reallocating a larger block of memory, in order to keep all its elements in a contiguous array. When it does that, each element is moved into the new memory, and the old elements are destroyed. That's why you sometimes see more than one destructor call.
如果您知道向量的最终大小,则可以避免重新分配的需要,方法是在开始之前调用 reserve()
分配足够的内存.或者,还有像 deque
和 list
这样的容器,它们不会随着元素的增长而移动它们的元素,但对于其他操作来说可能效率较低.
You can avoid the need for reallocation, if you know the final size of the vector, by calling reserve()
to allocate enough memory before you start. Alternatively, there are containers like deque
and list
which don't move their elements as they grow, but which may be less efficient for other operations.
顺便说一句,如评论中所述,如果该类正在管理资源(这意味着存在析构函数),您可能需要提供或删除复制构造函数和复制赋值运算符三法则,也许考虑让它移动以提高效率.
As an aside, as noted in the comments, if the class is managing resources (which is implied by the presence of a destructor), you probably need to provide or delete the copy constructor and copy-assignment operator per the Rule of Three, and perhaps think about making it movable for efficiency.
相关文章