標籤:ack 函數 ast first func 容器 src 資料 argc
list是C++ stl的一個很普通的容器。這篇文章不會去討論每種介面的用法,我認為那隻是流於表面的應用,網上有很多例子。
先拿一個簡單的介面看一下:
void push_back ( const T& x );
它的說明如下
Add element at the end
Adds a new element at the end of the list, right after its current last element. The content of this new element is initialized to a copy of x.
This effectively increases the list size by one.
上面這些話的意思是:將一個元素x加到list的尾部,加入的內容是x的一份拷貝。這句話很重要,我們push_back的只是一個對象的副本。
因此,假如我們需要將對象放在list容器裡面去管理,同時我們又會在其他流程裡面更新這些對象的資訊,那麼list內的副本資訊時不會受到任何修改的。
這顯然不是我們要的結果。因此,我們用list管理對象的時候,最後傳入所要管理對象的指標。
由此,會引出另外一個問題。我們先看一下另外一個介面:
void pop_front ( );
它的說明如下:
Delete first element
Removes the first element in the list container, effectively reducing the list size by one.
This calls the removed element‘s destructor.
重點看最後一句話,當這個對象被pop出來後,這個對象的解構函式會被調用。假如我們一開始push_back的是一個對象,那麼根據之前的討論,實際上存入的是該對象的副本,‘
當pop的時候,副本的解構函式會被調用。但是如果我們一開始push_back的是對象的指標呢?那麼該對象會不會被析構呢?
答案是不會。原因是,像指標,int,double這種都是基本的資料類型,不是對象,不會被析構。
看一段代碼吧:
class TEST{public: TEST() { cout << "constructor" << endl; return; } ~TEST() { cout << "deconstruction" << endl; }};void func(void){ TEST *test = new TEST(); std::list<TEST*> testList; testList.push_back(test); testList.pop_front();
return;}void gunc(void){ TEST test; std::list<TEST> testList; testList.push_back(test); test = testList.front(); testList.pop_front();}
#include<iostream>#include <list>using namespace std;int main(int argc, char**argv){func(); cout<<"--------分割線---------"<<endl;gunc();return 0;}
分析:
func內,我們new了一塊動態記憶體,並將該指標放入了list裡面,然後我們又把它pop出來,但是整個函數執行完成後,都沒有調用解構函式,這就造成了記憶體泄露。
gunc內,我們產生了一個局部對象test,並將對象push進了list內,根據前面的討論我們知道實際上push進去的是test的副本,因此pop的時候調用的
解構函式,實際上是test副本的解構函式,當結束當前調用棧的時候,局部變數test的解構函式被自動調用,因此可以看到兩次析構的列印。
關於C++的STL中list的理解