【问题标题】:Maintaining multiple class instances (objects) wihout destructor calls in c++在 C++ 中维护多个类实例(对象)而不调用析构函数
【发布时间】:2021-03-25 18:09:14
【问题描述】:

我想制作许多“学生”类型的对象并将它们存储起来,以便在整个程序中使用它们。我还需要在创建和销毁学生时打印出消息,但是当我将“已销毁”消息放入析构函数时,每当我更改实例以创建下一个学生时,它就会出现,因为调用了析构函数。有没有办法绕过它,只在我的程序结束时为每个对象调用析构函数?

每当要创建下一个学生(每个 for 循环)时,当前的这段代码都会销毁每个学生,然后在程序结束时再次“重新销毁”。我只希望它们在最后被删除。

#include <iostream>
#include <string>

class Student{  
    // members
public:

    Student(){}
    Student(std::string name, int floor, int classroom ){
        std::cout<<"Student created\n\n";
        // assignments
    }
    ~Student(){std::cout<<"Student destroyed\n\n";}
       // methods
};

int main(int argc, char** argv) {

Student* S=new Student[5];

for (int i=0; i<5; i++){
    S[i]=Student("example", 1,1); //makes 5 students and stores them
}

// rest of the program

delete[] S;

return 0;
}

【问题讨论】:

  • 你认为为什么每个学生都在循环中被摧毁?您将它们存储在一个数组中。
  • S[i]=Student("example", 1,1); 创建一个Student 类型的临时对象,使用参数"example"11 进行初始化,分配S[i] 成为一个copy 临时的,并销毁临时的。
  • 此外,在标准 C++(自 1998 年以来)中,最好避免(直接)使用运算符 newdelete - 在担心调用析构函数的频率之前先尝试学习如何做到这一点.在很多情况下,它可以更轻松地避免不必要的对象构造和破坏。
  • 将赋值运算符代码添加到您的类并在调用时打印。

标签: c++ oop object destructor


【解决方案1】:

你从循环中看到的析构函数不是被析构的数组元素,而是你由Student("example", 1,1)创建的临时对象

声明

S[i]=Student("example", 1,1);

本质上等于

Student temporary_object("example", 1, 1);
S[i] = temporary_object;

如果您想创建五个对象,其中每个对象的初始化完全相同(这就是您正在做的事情),那么请使用带有显式初始化程序的 std::vector

std::vector<Student> S(5, Student("example", 1,1));

对于您在 std::vector 构造函数调用中创建的临时对象,这仍将调用一次析构函数。


一种方法可以跳过临时对象的创建,但这也需要使用向量:

std::vector<Student> S;
S.reserve(5);  // Reserve memory enough for five elements

for (unsigned i = 0; i < 5; ++i)
{
    S.emplace_back("example", 1, 1);  // Construct in-place in the vector,
                                      // no temporary object creted
}

请注意,reserve 调用对于避免向量的重新分配很重要,这涉及可能的数据复制和旧数据的破坏

【讨论】:

  • 每个对象的初始化都是完全相同的,只是在这个例子中,而不是在我正在制作的实际程序中。所以我用你的解决方案和向量来跳过临时对象的创建,谢谢!矢量会自动删除,所以我不必担心释放内存,对吧?还尝试了 2 个 Student 和 Teacher 类型的向量,我第一个声明的那个似乎最后被删除了,很有趣。
  • @GeorgeT 是的,std::vector 对象维护自己的内存,您无需执行任何操作。此外,对象以相反的定义顺序(在 C++ 规范中指定)被破坏。
猜你喜欢
  • 2021-04-10
  • 1970-01-01
  • 2020-03-22
  • 2011-03-07
  • 1970-01-01
  • 2011-01-07
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多