当使用Vectors创建对象时,如何调用析构函数

时间:2015-05-28 15:16:41

标签: c++ vector destructor

我对如何通过向量构造的对象调用析构函数感到有点困惑,但是当我使用指针创建对象时,只有一次。

#include <iostream>
#include <vector>
#include <string>

class Student
{
    std::string first;
    std::string last;
    int age;

public:
    Student();
    Student(std::string f, std::string l, int a) : first(f), last(l), age(a)
    {
    };
    ~Student()
    {
        cout << "Destructor\n";
    }
};

int main()
{
    std::vector<Student> Univ;
    Univ.push_back(Student("fn1", "ln1", 1));
    Univ.push_back(Student("fn2", "ln2", 2));
    Univ.push_back(Student("fn3", "ln3", 3));
    return 0;
}

当我向后推一次时,我得到2次调用析构函数。 2推回,我得到了5个析构函数的调用。 3推回,我得到了9个析构函数。

通常如果我这样做,

Student * Univ = new Student("fn1", "ln1", 1);
delete Univ;

我只打了一次析构函数。

为什么会这样?

3 个答案:

答案 0 :(得分:2)

您正在创建一个临时Student,您将其传递给push_back,并将其复制到矢量中。结果是你使用每个Student实例的两个副本,并且每个实例的析构函数都被调用。此外,当您添加更多Student并且向量调整大小时,现有内容将复制到新分配的内存中,从而导致更多析构函数调用。

如果您有可用的C ++ 11功能,则可能需要查看move semantics

答案 1 :(得分:1)

当你执行push_back并且向量没有足够的内存来存储它必须调整大小的新元素时,每次向量调整大小时它都会调用旧元素的析构函数。试试这个:

std::vector<Student> Univ(3);
Univ.push_back(Student("fn1", "ln1", 1));
Univ.push_back(Student("fn2", "ln2", 2));
Univ.push_back(Student("fn3", "ln3", 3));

除此之外,您正在创建要传递给push_back的临时对象,这就是额外析构函数调用的原因。

答案 2 :(得分:1)

  

当我向后推一次时,我得到2次调用析构函数。 2推回,   我得到了5个析构函数的调用。 3推回,我接到9个电话   析构函数。

在C ++ 11之前,当您将对象推回到std::vector系统时,将对象复制到容器中。所以如果你做一个推回系统创建了2个对象,那么系统必须调用2次析构函数来清理。

从C ++ 11开始,如果为调用定义移动复制构造函数,std :: vector使用移动语义代替复制构造函数,并将对象移动到vector而不是复制对象。因此系统将只生成一个析构函数调用。  以下链接可让您更好地了解http://en.cppreference.com/w/cpp/language/rule_of_three