【问题标题】:Destructor called twice析构函数调用了两次
【发布时间】:2016-06-07 23:05:25
【问题描述】:

编辑:事实证明,无论我是否使用向量,都会发生这种情况。尽管我尝试显式调用析构函数,但它与具有自动销毁功能的函数的本地对象有关。

我试图弄清楚为什么我的对象显然被删除了两次。我正在试验 std::vector 类,想看看如何处理对象的删除。谁能告诉我在这种情况下发生了什么?

代码:

#include<iostream>
#include<vector>
#include"DummyClass.h"
using namespace std;

void main(void){
    //Make vector
    vector<DummyClass> objVect1;

    //Make objects to contain
    DummyClass test;

    //pass by value
    objVect1.push_back(test);   //makes a pass-by-value copy, I think?


    //Delete the objects stored in the array 
    objVect1.clear();   // call dtor (vector's copy)

    test.~DummyClass(); //call dtor on test
}                       //dtor called on test again?

控制台输出:

0033F9DB was constructed
0062C200 was destructed
0033F9DB was destructed
0033F9DB was destructed

最后一个对象被破坏了两次。我试图弄清楚发生了什么。似乎没有为传递给向量的按值复制参数调用构造函数。谁能帮我解决这个问题?谢谢!

类头是:

#pragma once
#include<iostream>
class DummyClass
{
public:
    DummyClass();
    ~DummyClass();
};

类cpp是:

DummyClass::DummyClass()
{    
    std::cout << this << " was constructed" << std::endl;
}

DummyClass::~DummyClass()
{
    std::cout << this << " was destructed"<< std::endl;
}

【问题讨论】:

  • 你确定向量与此有关吗?您是否尝试删除它? (反问。)
  • 其实我只是把它去掉了,你是对的,向量不是问题的一部分。
  • void main 产生 未定义的行为,因为它是无效的。之后你就没有任何保证了。
  • 它被称为 destructor 而不是 deconstructor
  • 你为什么要自己调用析构函数???

标签: c++ vector


【解决方案1】:

最后一个对象被解构两次。

当你显式地破坏它时,然后当函数结束并且函数本地的所有变量自动破坏时再一次。这是未定义的行为。

您几乎不应该自己调用析构函数。

【讨论】:

    【解决方案2】:
    DummyClass test;
    

    此对象在main 函数中,当main 返回时将超出范围。 (调用了 1 个析构函数)

    objVect1.push_back(test);
    

    DummyClass 的副本被添加到std::vector

    objVect1.clear();
    

    当调用clear 时副本被销毁。 (调用了 1 个析构函数)

    test.~DummyClass()
    

    您不应显式调用此析构函数,它会在对象超出范围时自动发生(即,当main 函数返回时)。 (调用了 1 个析构函数)

    析构函数被调用3 次,如上所示,用于2 对象实例。应该删除显式的析构函数调用。

    【讨论】:

      【解决方案3】:

      您不需要在 main 结束时调用析构函数。一旦“测试”超出范围,它就会自动调用。删除 main 的最后一行。

      【讨论】:

        【解决方案4】:

        push_back() 将test 复制到向量中。当向量被clear()ed 时,第一次调用析构函数,向量中的副本被销毁。

        当您显式调用析构函数时,它会在第二次被调用。

        main() 第三次返回时,test 被真正摧毁了。

        【讨论】:

          【解决方案5】:

          我无法发表评论,但我认为第一次调用是在 clear 之后进行的,test 对象被破坏;第二个是由您调用的。

          【讨论】:

            猜你喜欢
            • 2021-07-03
            • 2012-08-06
            • 2010-12-29
            • 1970-01-01
            • 2017-05-24
            • 2013-01-12
            • 2019-08-02
            • 1970-01-01
            相关资源
            最近更新 更多