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函数中我们还能够使用此地址访问此地址对应的资源!


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值