Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当使用向量创建对象时,如何调用析构函数_C++_Vector_Destructor - Fatal编程技术网

C++ 当使用向量创建对象时,如何调用析构函数

C++ 当使用向量创建对象时,如何调用析构函数,c++,vector,destructor,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:

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

#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;
}
我只接到了一个叫析构函数的电话


这是为什么?

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


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

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

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));
std::矢量大学(3);
大学推回(学生(“fn1”,“ln1”,1));
大学推回(学生(“fn2”,“ln2”,2));
大学推回(学生(“fn3”,“ln3”,3));
除此之外,您正在创建要传递到
push_back
的临时对象,这就是额外析构函数调用的原因

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

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

从C++11开始,如果为调用定义移动复制构造函数,std::vector将使用移动语义代替复制构造函数,并将对象移动到vector,而不是复制对象。所以系统将只生成一个析构函数调用。
下面的链接将给你更好的想法

可能向量空间不足,在其他地方获得了更多空间,并将学生复制或移动到新空间。然后在旧空间为学生调用了析构函数。@nwp在一个较大的程序中,有大量的后推,这会是一个缺点吗?这是无法避免的,除非你事先知道大小。但是调整大小的情况很少发生,所以不要太担心。如果您能猜出大小,可以使用vector.reserve(大小)。列表没有这个问题,但它们还有其他更糟糕的问题。在C++11中,使用移动语义可以大大减少开销。如果复制/移动对象非常昂贵,可以使用指向对象的指针。这将最小化调整大小的成本,但会增加访问成本,使事情变得不那么方便。请注意,如果他只是删除他的析构函数,他将免费获得移动语义。
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));