簡體   English   中英

推入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)和四個析構函數。 有五個破壞者會讓我感到驚訝。

您只看到兩個“ I am the constructor for... ”,因為您忘記添加復制構造函數:

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

正如Barry在他的回答中提到的那樣,由於重新分配,您會看到5個析構函數。 您可以在向量上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 

五個破壞者:

  • main() int1int2每個兩個
  • l必須重新分配以容納更多成員時,用於l的對象。
  • l持有MyInt的兩個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM