我对如何通过向量构造的对象调用析构函数感到有点困惑,但是当我使用指针创建对象时,只有一次。
#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;
我只打了一次析构函数。
为什么会这样?
答案 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