c++ - std::vector 在 push_back 期间多次调用析构函数?

标签 c++ c++11 vector

我将对象类 tipo 推送到一个 vector ,当我推送第一个时,构造函数 get 被调用(它应该)并且析构函数被立即调用(我认为这不应该发生)。然后,当我推送下一个对象时,构造函数被调用一次,析构函数被调用两次,然后在第三次被调用三次,依此类推。

似乎每次我向 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

我做错了什么吗?为什么会这样?

最佳答案

您的每一行代码都会创建一个临时的 Item ,将它复制到 vector 的内存中,然后销毁临时的。这就是为什么您每次看到(至少)一个析构函数调用。

在 C++11 中,您可以使用 emplace_back(args...) 避免创建和销毁临时对象而不是 push_back(Item(args...)) , 直接在 vector 的内存中创建对象。

此外, vector 有时需要增长,重新分配更大的内存块,以便将其所有元素保存在一个连续的数组中。当它这样做时,每个元素都被移动到新内存中,旧元素被销毁。这就是为什么您有时会看到不止一个析构函数调用的原因。

如果知道 vector 的最终大小,可以通过调用 reserve() 来避免重新分配的需要。在开始之前分配足够的内存。或者,有类似 deque 的容器和 list它不会随着它们的增长而移动它们的元素,但对于其他操作来说可能效率较低。

顺便说一句,如注释中所述,如果该类正在管理资源(析构函数的存在暗示了这一点),您可能需要提供或删除复制构造函数和复制赋值运算符Rule of Three ,也许考虑让它可移动以提高效率。

关于c++ - std::vector 在 push_back 期间多次调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59304030/

相关文章:

c++ - C++ 中的稀疏图实现和性能

c++ - 使用带有 pure_out_value 策略的 std::string& Reference 的 Luabind 函数不可能吗?

c++ - 在opengl中用线程绘制顶点

c++ - 如何使用 clang 获取单个 cpp 文件的 AST?

c++ - nullptr 不能在 valarray 中使用

c++ - std::chrono::duration::count 函数的实际结果类型是什么

c++ - C++11 std::bind 的链式调用不起作用

c++ - std::sort() 中的程序有时会崩溃,无法重现

Java Applet - For 循环递减组件堆栈

c++ - 使用插入时自动调整 std::vector 的大小