4

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

每次我将某些东西推送到向量时,似乎都会调用更多次析构函数。

这是我的课:

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

难道我做错了什么?为什么会发生这种情况?

4

1 回答 1

14

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

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

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

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

顺便说一句,如评论中所述,如果该类正在管理资源(这由析构函数的存在暗示),您可能需要根据三规则提供或删除复制构造函数和复制赋值运算符,并且也许考虑使其可移动以提高效率。

于 2013-11-10T15:35:59.960 回答