在推送到C ++向量时,构造函数和析构函数调用

时间:2016-03-03 17:58:15

标签: c++ constructor destructor

以下代码

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)和四个析构函数。有五个破坏者让我感到惊讶。

2 个答案:

答案 0 :(得分:2)

您只看到两个“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 

答案 1 :(得分:0)

五个析构函数:

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