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

use*_*283 8 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; 
}
Run Code Online (Sandbox Code Playgroud)

输出:

构造函数:1

析构函数:0

构造函数:1

析构函数:0

析构函数:-1

当前值k = -1

2

析构函数:-2

析构函数:-3

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

Lig*_*ica 4

您正在制作副本,但您的跟踪输出没有显示这一点(并且k当发生这种情况时您的跟踪输出不会增加)。因此,“额外的”析构函数调用与复制结构一起进行。

您可以通过正确使用删除其中一份副本emplace

test.emplace(test.end());
//                     ^ no A() here; that would be like doing test.push_back(A(A()))
Run Code Online (Sandbox Code Playgroud)

但您仍然拥有其本身的副本push_back

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

A(const A&) { k++; cout << "copy-constructor : " << k << endl; }
Run Code Online (Sandbox Code Playgroud)

(我不会为移动构造函数而烦恼,因为这将导致delete复制赋值运算符,所有的地狱都会崩溃。)


完成代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

现场演示