void deleteAllNodes()
{
stack <parentBranch *> mystack;
// `trunk` is the existing head node
mystack.push (trunk);
cout << mystack.top()->content;
}
在這種情況下,樹幹的「副本」會被推入堆棧嗎?那麼,這是否意味着一次存在兩條中繼線?當一個已經存在的指針被推入堆棧時,它的副本是否被創建?
void deleteAllNodes()
{
stack <parentBranch *> mystack;
// `trunk` is the existing head node
mystack.push (trunk);
cout << mystack.top()->content;
}
在這種情況下,樹幹的「副本」會被推入堆棧嗎?那麼,這是否意味着一次存在兩條中繼線?當一個已經存在的指針被推入堆棧時,它的副本是否被創建?
沒有。 trunk
指向一個對象,但不是對象本身。就像在汽車旁邊寫着「Car - >」的標誌一樣。當您將trunk
推到mystack
時,您不會再購買另一輛車。你只是得到另一個指向同一輛車的標誌。
如果您將車開走(例如:delete trunk;
),會有些不好。然後你會看到一大堆指向一輛汽車的標誌,但是當有人出現並嘗試進入該汽車時,它們會落在後方。指向汽車的所有標誌都是騙子。
不,只有一個trunk
但指向它的兩個指針。
就是這個原因,標準庫容器不採取所有權解除分配指針成員的記憶,因爲他們無法確定究竟是誰擁有對象被指向駐留容器或一個內部的指針用於推送操作。
如果您使用指針作爲容器元素,則不得不執行手動內存管理,這取決於用戶確保指向的對象保持有效。
這是人們應該使用智能指針而不是原始指針與標準庫容器的原因,它可以節省您手動內存管理。
如果被推入的元素不是一個指針,而是一個對象,則會有兩個單獨的對象副本,一個存儲在容器中,另一個用於推入容器。
謝謝,很有幫助。你是指普通的對象,如果推送會創建自己的副本?淺拷貝? – 2012-02-02 07:05:08
@AnishaKaul:是一個副本,通過調用* copy構造函數*就像在函數調用過程中按值創建的副本一樣。這將是一個*淺拷貝*或*深拷貝*取決於拷貝構造函數的實現。 – 2012-02-02 07:06:50
A 指針副本被推入,但不是指向它的對象的副本。
好的,謝謝。那麼,這是否意味着如果我們刪除了我們在棧中推送的指針,我們實際上刪除了原始主幹? – 2012-02-02 07:02:17
@AnishaKaul,是的,實際的'trunk'指針的對象被從堆中刪除。因爲這兩個指針都指向相同的位置。 – iammilind 2012-02-02 07:03:43
@AnishaKaul:你會留下一個懸掛指針和一個UB。 – 2012-02-02 07:04:00
也謝謝你(很好的例子)。那麼,這是否意味着如果我們刪除了我們在棧中推送的指針,我們實際上刪除了原始主幹? – 2012-02-02 07:03:50
是的,這是正確的。爲了澄清,如果你'刪除mystack.top();',你創建的原始對象將被銷燬。當然,你總是可以擺脫指針('mystack.pop();')。這對原始對象沒有任何作用。 – Managu 2012-02-02 07:05:18