STL Container 的 destroy

因為工作的緣故,想要了解一下,如果我把物件丟到 STL Container 裡面的時候,C++會怎麼幫我 destroy, 所以寫了以下這支小程式來驗證一下:

#include <iostream>
#include <string>
#include <vector>
class node {
public:
node();
node( string s );
node( char* s );
~node();
private:
string m_string;
};
node::node() {
m_string="";
cout << "initialize " << m_string << endl;
}
node::node(string s):m_string(s) {
cout << "initialize " << m_string << endl;
}
node::node(char* s):m_string(s) {
cout << "initialize " << m_string << endl;
}
node::~node() {
cout << "destroy " << m_string << endl;
}
int main(void) {
vector<node> vector_test1;
vector<node*> vector_test2;
cout << "Non-Pointer Version" << endl;
vector_test1.push_back( node("test1") );
vector_test1.push_back( node("test2") );
vector_test1.push_back( node("test3") );
vector_test1.push_back( node("test4") );
vector_test1.push_back( node("test5") );
vector_test1.push_back( node("test6") );
vector_test1.push_back( node("test7") );
vector_test1.push_back( node("test8") );
vector_test1.push_back( node("test9") );
vector_test1.push_back( node("test10") );
cout << endl << "Pointer Version" << endl;
vector_test2.push_back( new node("test1") );
vector_test2.push_back( new node("test2") );
vector_test2.push_back( new node("test3") );
vector_test2.push_back( new node("test4") );
vector_test2.push_back( new node("test5") );
vector_test2.push_back( new node("test6") );
vector_test2.push_back( new node("test7") );
vector_test2.push_back( new node("test8") );
vector_test2.push_back( new node("test9") );
vector_test2.push_back( new node("test10") );
}

執行以後的結果很有趣.
在我的機器上是這樣子的:

Non-Pointer Version
initialize test1
destroy test1
initialize test2
destroy test1
destroy test2
initialize test3
destroy test1
destroy test2
destroy test3
initialize test4
destroy test4
initialize test5
destroy test1
destroy test2
destroy test3
destroy test4
destroy test5
initialize test6
destroy test6
initialize test7
destroy test7
initialize test8
destroy test8
initialize test9
destroy test1
destroy test2
destroy test3
destroy test4
destroy test5
destroy test6
destroy test7
destroy test8
destroy test9
initialize test10
destroy test10
Pointer Version
initialize test1
initialize test2
initialize test3
initialize test4
initialize test5
initialize test6
initialize test7
initialize test8
initialize test9
initialize test10
destroy test1
destroy test2
destroy test3
destroy test4
destroy test5
destroy test6
destroy test7
destroy test8
destroy test9
destroy test10

這說明了幾件事情:
1.如果我不是利用 new 去建立物件,而是利用宣告建立物件的話
c++只是把建立好的物件複製一份到 container 中,接著就釋放他了
如果是利用 new 去建立物件,那麼在程式的最後,container 會自動呼叫每個元素的 解構子 destroyer 去解構,而無須我們再手動去解構他們.
2.vector 會自我成長,但是在成長的時候,會同樣利用複製的方式,把原本在 container 的資料複製到新的 container 裡面去,但這樣子不是很有效率