类对象作为向量元素,析构函数被调用太多次

时间:2016-04-08 09:43:28

标签: c++ destructor

#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class A
{
    static int k;
    public:
    A(){k++ ; cout << "constructor : " <<k<< endl;};
    ~A(){k--; cout << "destructor : "  << k <<endl;};
    void show() { cout<<"current value of k = "<<k<<endl; }
};
int A::k = 0;
int main( )
{
    vector<A> test;
    test.push_back(A());
    test.emplace(test.end(), A()); 
    test[0].show();
    cout<<test.size()<<endl;
    return 0; 
}

输出:

  

构造函数:1

     

析构函数:0

     

构造函数:1

     

析构函数:0

     

析构函数:-1

     

当前值k = -1

     

2

     

析构函数:-2

     

析构函数:-3

为什么析构函数被调用了太多次,因为它应该被调用两次,因为构造函数只被调用两次?如何避免这种情况?

2 个答案:

答案 0 :(得分:4)

您正在制作副本,但您的跟踪输出未显示(并且k在发生时不会增加)。所以“额外的”析构函数调用与复制结构一起使用。

您可以正确使用emplace删除其中一个副本:

test.emplace(test.end());
//                     ^ no A() here; that would be like doing test.push_back(A(A()))

但你仍然在push_back本身有一份副本。

编写一个复制构造函数,以便跟踪输出考虑这些操作:

A(const A&) { k++; cout << "copy-constructor : " << k << endl; }

(我不打扰移动构造函数,如that'll delete the copy assignment operator and all hell will break loose。)

完成的代码:

#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class A
{
    static int k;

public:
    A()         { k++; cout << "constructor : "      << k << endl; }
    ~A()        { k--; cout << "destructor : "       << k << endl; }
    A(const A&) { k++; cout << "copy-constructor : " << k << endl; }

    void show() { cout << "current value of k = " << k << endl; }
};

int A::k = 0;

int main()
{
    vector<A> test;

    test.push_back(A());
    test.emplace(test.end(), A());

    test[0].show();
    cout << test.size() << endl;
}

输出:

constructor : 1
copy-constructor : 2
destructor : 1
constructor : 2
copy-constructor : 3
copy-constructor : 4
destructor : 3
destructor : 2
current value of k = 2
2
destructor : 1
destructor : 0

live demo

答案 1 :(得分:3)

正在使用编译器生成的复制构造函数,该构造函数不会增加k

在源代码中明确包含该内容,一切都会很好。