【问题标题】:Does the C++ queue destroy the object after pop?C++队列会在pop后销毁对象吗?
【发布时间】:2019-08-15 07:45:04
【问题描述】:

先显示一些简单的代码:

A 类:

//create a queue

queue<my_class*> temp;
//add some element some pointers;

temp.push(A);
temp.push(B);
...

//then i want to delete the first element ;

temp.pop();

问题一: 调用 temp.pop() 时会释放所有对象内存 一个用过? 如果没有,我该怎么办?

B型:

//create a queue

queue<my_class> temp;
//add some element some pointers;

temp.push(A);
temp.push(B);
...

//then i want to delete the first element ;

temp.pop();

问题2:A型和B型有什么区别;

【问题讨论】:

    标签: c++


    【解决方案1】:

    Q2: pop 对于 Type AType B 做同样的事情,pop 破坏了定义的类型在模板参数中(对于 Type A,它是一个指向 my_class 的指针,对于 Type B 它是 my_class)。所以Type A 破坏了一个指针Type B 破坏了my_class 的一个实例。

    Q1:是的,因为A 只是一个指针。但它不会破坏A 指向的对象。所以my_class的实例没有被释放。

    【讨论】:

      【解决方案2】:

      pop() 确实破坏了第一个元素。

      但是请注意,在第一种情况下,std::queue裸指针,并且销毁裸指针不会对指向的对象做任何事情。

      在第二种情况下,std::queue 包含 对象副本,因此在调用 pop() 时,第一个副本将被销毁并删除。

      在第一种情况下,除非其他人知道被销毁指针指向的对象的地址并在该地址上调用delete,否则该对象将被“泄露”(即被遗忘):它的析构函数永远不会被调用并且它正在使用的内存将永远不会被回收并重新用于其他用途。

      在第一种情况下销毁指向的对象,正常的过程是

      delete queue.front();
      queue.pop();
      

      如果您使用“智能”指针而不是“裸”指针,那么“泄漏”问题在大多数情况下都会消失(*)。请注意,这并不意味着指向对象的析构函数将在pop() 中调用,而是它将在其他人不知道指向对象的地址的适当时间调用(如果一切都完成了操作智能指针时正确)。


      (*) 如果您的数据模型很复杂,并且您有std::shared_ptr 对象网络相互指向,则存在创建“引用循环”的风险。在这种情况下,std::shared_ptr 即使正确使用也不足以防止循环泄漏(例如,泄漏一组对象AB,其中每个对象都有一个std::shared_ptr),并且真正的垃圾收集器是需要。不幸的是,C++ 并没有在标准库中提供这种机制。

      【讨论】:

      • 当然应该更喜欢智能指针,而不是手动删除,比如std::queue&lt;std::unique_ptr&lt;my_class&gt;&gt;
      • @chtz 你能给我一个关于如何使用std::queue的演示代码<:unique_ptr>>
      • @chtz:我已经添加了关于智能指针的注释......它们很好,但重要的是要记住它们不是灵丹妙药。 C++ 中唯一的选择是认真考虑所有权(或实现/使用垃圾收集器)。
      • @6502 没错,按值存储应该始终是第一选择。仅当这太昂贵(或存在其他约束)时,才应考虑存储(智能)指针。在 OP:stackoverflow.com/questions/14127487/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-08
      • 2012-06-25
      • 2014-10-11
      • 2021-10-31
      • 1970-01-01
      • 2011-09-18
      相关资源
      最近更新 更多