推入C++向量时的构造函数和析构函数调用

Constructor and destructor calls when pushing on to a C++ vector

本文关键字:析构 函数调用 构造函数 C++ 向量 推入      更新时间:2023-10-16

对于以下代码

struct MyInt {
  MyInt() { 
    std::cout << "I am the constructor for " << val << "n";
  }
  ~MyInt() {
    std::cout << "I am the destructor for " << val << "n";
  }
  int val;
};
int main() {
    using namespace std;
    cout << "Constructing l:" << endl;
    vector<MyInt /*, Mallocator<MyInt>*/ > l;
    MyInt int1;
    MyInt int2;
    int1.val = 1729;
    int2.val = 2161;
    cout << "Push back the itemn";
    l.push_back(int1);
    l.push_back(int2);
  return 0;
}

为什么我得到以下输出?

Constructing l:
I am the constructor for 1558899544 (garbage)
I am the constructor for 47517696 (garbage)
Push back the item
I am the destructor for 1729
I am the destructor for 2161
I am the destructor for 1729
I am the destructor for 1729
I am the destructor for 2161

我假设有四个构造函数(两个用于 int1 和 int2,两个用于 push_back)和四个析构函数。有五个析构函数让我感到惊讶。

您只看到两个" I am the constructor for... ",因为您忘记添加复制构造函数:

MyInt(const MyInt& rhs) 
{ 
    std::cout << "I am the constructor copyn";
    val = rhs.val;
}

你会看到 5 个析构函数,因为重新分配,正如 Barry 在他的回答中提到的。您可以reserve向量的大小,您将只看到预期的 4 个析构函数:

l.reserve(2); // 2 will suffice for the example at hand

将其添加到代码中可能会输出(正如PaulMcKenzie指出的那样,编译器可以自由删除复制结构,因此最终输出可能取决于编译器,编译器设置,优化):

Constructing l:
I am the constructor default
I am the constructor default
Push back the item
I am the constructor copy
I am the constructor copy
I am the destructor
I am the destructor
I am the destructor
I am the destructor 

五个析构函数:

  • int1int2各两个main()
  • 一个用于l内部的对象,当它必须被重新分配以容纳更多的成员时。
  • 两个为l持有的MyInt