【问题标题】:How does destructor gets called when object are created using Vectors使用向量创建对象时如何调用析构函数
【发布时间】:2015-08-11 04:49:20
【问题描述】:

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

#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;

我只接到一个析构函数调用。

这是为什么?

【问题讨论】:

  • 可能是向量空间不足,在别处获得了更多空间并将学生复制或移动到新空间。然后为旧空间中的学生调用析构函数。
  • @nwp 在一个较大的程序中,有大量的后退,这会是一个缺点吗?
  • 这是无法避免的,除非你事先知道尺寸。但是调整大小很少发生,所以不要太担心。如果你能猜到大小,你可以使用vector.reserve(size)。列表没有这个问题,但它们还有其他更严重的问题。在 C++11 中,您可以通过移动语义大大减少开销。如果对象的复制/移动成本非常高,则可以使用指向对象的指针。这将最大限度地减少调整大小的成本,但会增加访问成本并使事情变得不那么方便。

标签: c++ vector destructor


【解决方案1】:

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

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

【讨论】:

  • 请注意,如果他简单地删除他的析构函数,他将免费获得移动语义。
【解决方案2】:

当我推回一次时,我收到了 2 次析构函数调用。 2 推背, 我接到 5 次析构函数调用。 3 次回击,我接到 9 个电话 析构函数。

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

从 C++11 开始,如果为调用定义移动复制构造函数,std::vector 使用移动语义代替复制构造函数并将对象移动到向量而不是复制对象。所以系统只会产生一个析构函数调用。 以下链接将为您提供更好的想法http://en.cppreference.com/w/cpp/language/rule_of_three

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2013-03-07
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 2019-07-25
      • 2018-05-28
      • 1970-01-01
      相关资源
      最近更新 更多