为什么类的析构函数被调用两次?

时间:2010-04-13 06:49:46

标签: c++ destructor

道歉,如果问题听起来很愚蠢,我就是在关注SO的专家并亲自尝试一些例子,这就是其中之一。我确实尝试过搜索选项,但没有找到这种答案。

class A
{
    public:
         A(){cout<<"A Contruction"<<endl;}
        ~A(){cout<<"A destruction"<<endl;}
};

int main()
{
    vector<A> t;
    t.push_back(A()); // After this line, when the scope of the object is lost.
}

为什么类的析构函数被调用两次?

5 个答案:

答案 0 :(得分:42)

要添加元素,请在临时对象上调用复制构造函数。在push_back()临时对象被销毁之后 - 这不是第一个析构函数调用。然后vector实例超出范围并销毁存储的所有元素 - 这是第二个析构函数调用。

答案 1 :(得分:25)

这将显示happening

的内容
struct A {
  A() { cout << "contruction\n"; }
  A(A const& other) { cout << "copy construction\n"; }
  ~A() { cout << "destruction\n"; }
};

int main() {
  vector<A> t;
  t.push_back(A());
}

答案 2 :(得分:4)

当发送到push_back的临时值被销毁时,析构函数被调用一次,而t中的元素被销毁时,析构函数被调用一次。

答案 3 :(得分:2)

有两个析构函数调用,因为有两个对象:push_back的参数和vector t中新添加的元素。

STL containers存储副本。在您的示例中,由push_back添加到vector的元素是从传递给push_back的参数构造的副本。参数为A(),这是一个临时对象,请参阅here (variant 4)

稍微扩展一下答案,尽管你没有明确要求它:知道临时被摧毁的时间可能会有用。标准(N4140)在12.2 p3中很清楚:

  

...临时对象作为评估的最后一步被销毁   full-expression(1.9)(词法上)包含它们的点   被创造了......

旁注:如果使用emplace_back,则只有一个对象。容器中的新元素直接由emplace_back的参数构造。许多STL容器在C ++ 11中学习了一个emplace变种。

答案 4 :(得分:0)

最有可能的是,您的对象副本正在创建中。因此,复制对象和原始对象的析构函数使call-count = 2。

示例:即使您将对象引用传递给某个类,也会在内部调用copy-constructor。为避免这种情况,子类(您要将父引用传递给它)必须为;

Parent *const &p parentRef;  //Child.h

然后,父对象将作为;

传递
// Parent.cpp
Parent *parentObj = this;
Child *childObj = Child(parentObj);

此外,您可以通过覆盖来调试copy-constructor invokation;

Parent(const Parent& object){
        cout <<"copy called.." << endl;
}
...

更多信息@stackoverflow@