這裏舉例一下MFC中的CPtrArray類,他是CObject類型指針對象的集合。通過int Add( CObject* newElement );注意參數是一個指針類型)可以向集合中添加元素。首先我們定義一個CPtrArray類型的對象。
CPtrArray
pArray;
在另一個函數中我們使用pArray容器爲我們保存的數據:
06 |
for ( int i;
i < pArray.GetSize();i++) |
08 |
a
= (A*)pArray.GetAt(i); |
現在我們發現按照上面的過程,當我們在func2()函數中將要使用pArray容器對象爲我們保存的數據時,我們並不能得到想要的數據!!!爲什麼發生以上情況?圖解如下
func1函數執行完成,a發生析構,資源不可用;
原來在func1()函數中,a對象是一個局部對象,當我們使用pArray.Add(&a);我們將a對象的地址保存到pArray對象中。但是作爲局部對象,當func1執行完成後,資源需要回收,此時我們定義的a對象也在A類中的析構函數中被析構釋放資源!而當我們在fun2()函數中執行取出保存的對象時,實際是根據保存的地址去內存中找到數據,雖然此時我們能能夠找到此地址,但是這個地址上面的數據並不是我們需要的了!!!所以才發生面的情況!那麼怎麼才能解決呢?看下面,我們只需更改func1函數中的一行代碼:
這樣,我們就能夠在func2函數中使用pArray對象中包含的數據了!那麼爲什麼定義了一個指針類型的對象就能夠完成了呢?還是一個局部對象呀,前面說的func1函數執行完成後此對象還是要經歷析構的啊!圖解如下:
pArray中保存a指向資源的地址;
func1函數執行完成,a對象發生析構,pArray根據地址還能能夠訪問到之前的資源;
對,是要析構,但是,我們在pArray.Add(a);中加入的是a對象資源的地址,我們先看看A* a = new A(1);在堆中分配資源,我們知道,在堆中分配的資源是在跟程序的生命週期是一致的。a對象雖然析構了(不存在了),因爲a也是一個指針,a指針也就是保存這個資源的地址!我們在pArray中保存的a的地址出的資源並沒有析構!所以在func2函數中我們還能夠使用此地址訪問此地址對應的資源!