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

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

对于下面的代码

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 item\n";

    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)和四个析构函数。有五个析构函数让我很惊讶。

五个析构函数:

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

你只看到两个“I am the constructor for...”因为你忘了添加复制构造函数:

MyInt(const MyInt& rhs) 
{ 
    std::cout << "I am the constructor copy\n";
    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