zoukankan      html  css  js  c++  java
  • 解析C++普通局部变量与指针类型的对象变量的应用区别

    首先我们先来了解一下MFC中的CPtrArray类,他可以说是CObject类型指针对象的集合。通过intAdd( CObject* newElement );注意参数是一个指针类型)可以向集合中添加元素。首先我们定义一个CPtrArray类型的对象。

    CPtrArray pArray;//他是一个全局对象

    先设定一个举例的类类型。如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class A
    {
    public:
        A(int i)
        {
            a = i;
        }
        ~A(){}
    public:
        int a;
    };

    现在我们需要在某个函数中要实现将一个A类型对象数据加入到一个CPtrArray对象中。此函数func1()如下:

    1
    2
    3
    4
    5
    6
    7
    void func1()
    {
        //首先定义一个A类型的对象
        A a(1);
        //使用pArray对象中的成员函数将此对象加入到容器中
        pArray.Add(&a);
    }

    在另一个函数中我们使用pArray容器为我们保存的数据:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void func2()
    {
        //首先声明一个A类型的对象
        A* a;
        //使用pArray对象中的成员函数GetAt()将A类型的对象取出
        for(int i; i < pArray.GetSize();i++)
        {
            a = (A*)pArray.GetAt(i);
            //使用A中的数据进行相关的操作代码。***此时也可以使用delete释放指针指向的内存区块,防止内存泄露***当然是后面一种方法时才用到,暂时无视之。
            ...
        }
         
    }

    现在我们发现按照上面的过程,当我们在func2()函数中将要使用pArray容器对象为我们保存的数据时,我们并不能得到想要的数据!!!为什么发生以上情况?图解如下

     

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

    func1函数执行完成,a发生析构,资源不可用;

    原来在func1()函数中,a对象是一个局部对象,当我们使用pArray.Add(&a);我们将a对象的地址保存到pArray对象中。但是作为局部对象,当func1

    行完成后,资源需要回收,此时我们定义的a对象也在A类中的析构函数中被析构释放资源!而当我们在fun2()函数中执行取出保存的对象时,

    实际是根据保存的地址去内存中找到数据,虽然此时我们能能够找到此地址,但是这个地址上面的数据并不是我们需要的了!!!所以才发生面的情况!

    那么怎么才能解决呢?

    看下面,我们只需更改func1函数中的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    void func1()
    {
        //首先定义一个A类型的对象
        //A a(1);//为对比,只是注释原来那句
        A* a = new A(1);
        //使用pArray对象中的成员函数将此对象加入到容器中
        pArray.Add(a);
    }

    这样,我们就能够在func2函数中使用pArray对象中包含的数据了!那么为什么定义了一个指针类型的对象就能够完成了呢?还是一个局部对象呀,

    前面说的func1函数执行完成后此对象还是要经历析构的啊!图解如下:

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

    func1函数执行完成,a对象发生析构,pArray根据地址还能能够访问到之前的资源;

    对,是要析构,但是,我们在pArray.Add(a);中加入的是a对象资源的地址,我们先看看A* a = new A(1);在堆中分配资源,我们知道,在堆中分配的资

    源是在跟程序的生命周期是一致的。a对象虽然析构了(不存在了),因为a也是一个指针,a指针也就是保存这个资源的地址!我们在pArray中保存

    的a的地址出的资源并没有析构!所以在func2函数中我们还能够使用此地址访问此地址对应的资源!

  • 相关阅读:
    android如何隐藏通知栏和禁止横屏竖屏切换
    android webview加载网页,文字listview和image混合listview的实现
    PHP加密3DES报错 Call to undefined function: mcrypt_module_open() 的解决方法
    http和HTTPS的区别及SSL介绍
    android SQLite数据库 一次性存储多条数据
    两个android程序间的相互调用(apk互调)
    android在学习——activity关闭和dialog.dismiss冲突的解决(Activity has leaked window com.android.internal.policy.impl.PhoneWindow)
    【android】解决因为图片太大引起的内存不足问题,Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
    android数据库操作 sqlite returned: error code = 14, msg = cannot open file at source line 25502
    android实现对SQLite数据库的增、删、改、查
  • 原文地址:https://www.cnblogs.com/xingrun/p/3451043.html
Copyright © 2011-2022 走看看