c++ 普通全局變量與指針類型的對象變量 應用區別

這裏舉例一下MFC中的CPtrArray類,他CObject類型指針對象的集合。通過int Add( CObject* newElement );注意參數是一個指針類型)可以向集合中添加元素。首先我們定義一個CPtrArray類型的對象。

CPtrArray pArray;//他是一個全局對象

先設定一個舉例的類類型。如:

01 class A
02 {
03 public:
04 A(int i)
05 {
06 a = i;
07 }
08 ~A(){}
09 public:
10 int a;
11 };

現在我們需要在某個函數中要實現將一個A類型對象數據加入到一個CPtrArray對象中。此函數func1()如下:

void func1()
2 {
3 //首先定義一個A類型的對象
4 A a(1);
5 //使用pArray對象中的成員函數將此對象加入到容器中
6 pArray.Add(&a);
7 }
在另一個函數中我們使用pArray容器爲我們保存的數據:

01 void func2()
02 {
03 //首先聲明一個A類型的對象
04 A* a;
05 //使用pArray對象中的成員函數GetAt()將A類型的對象取出
06 for(int i; i < pArray.GetSize();i++)
07 {
08 a = (A*)pArray.GetAt(i);
09 //使用A中的數據進行相關的操作代碼
10 ...
11 }
12 }
現在我們發現按照上面的過程,當我們在func2()函數中將要使用pArray容器對象爲我們保存的數據時,我們並不能得到想要的數據!!!爲什麼發生以上情況?圖解如下

pArray保存a保存資源的地址;


func1函數執行完成,a發生析構,資源不可用;

原來在func1()函數中,a對象是一個局部對象,當我們使用pArray.Add(&a);我們將a對象的地址保存到pArray對象中。但是作爲局部對象,當func1執行完成後,資源需要回收,此時我們定義的a對象也在A類中的析構函數中被析構釋放資源!而當我們在fun2()函數中執行取出保存的對象時,實際是根據保存的地址去內存中找到數據,雖然此時我們能能夠找到此地址,但是這個地址上面的數據並不是我們需要的了!!!所以才發生面的情況!那麼怎麼才能解決呢?看下面,我們只需更改func1函數中的一行代碼:

1 void func1()
2 {
3 //首先定義一個A類型的對象
4 //A a(1);//爲對比,只是註釋原來那句
5 A* a = new A(1);
6 //使用pArray對象中的成員函數將此對象加入到容器中
7 pArray.Add(a);
8 }
這樣,我們就能夠在func2函數中使用pArray對象中包含的數據了!那麼爲什麼定義了一個指針類型的對象就能夠完成了呢?還是一個局部對象呀,前面說的func1函數執行完成後此對象還是要經歷析構的啊!圖解如下:


pArray中保存a指向資源的地址;


func1函數執行完成,a對象發生析構,pArray根據地址還能能夠訪問到之前的資源;

對,是要析構,但是,我們在pArray.Add(a);中加入的是a對象資源的地址,我們先看看A* a = new A(1);在堆中分配資源,我們知道,在堆中分配的資源是在跟程序的生命週期是一致的。a對象雖然析構了(不存在了),因爲a也是一個指針,a指針也就是保存這個資源的地址!我們在pArray中保存的a的地址出的資源並沒有析構!所以在func2函數中我們還能夠使用此地址訪問此地址對應的資源!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章