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

How does destructor gets called when object are created using Vectors

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

#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 次后退,我收到 5 次析构函数调用。 3 次推回,我调用了 9 次析构函数。

通常如果我这样做,

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

我只调用了一次析构函数。

这是为什么?

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

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

当您执行 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 的临时对象,这就是调用额外析构函数的原因。

When I push back one time, I get 2 calls to destructor. 2 push backs, I get 5 calls to destructor. 3 push backs, I get 9 calls to destructor.

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

自 C++11 起,如果您为调用定义移动复制构造函数,std::vector 使用移动语义代替复制构造函数并将对象移动到矢量而不是复制对象。所以系统只会产生一个析构函数调用。 关注link会给你更好的想法http://en.cppreference.com/w/cpp/language/rule_of_three