第37课 智能指针分析(指针特征操作符( -> 、 *)重载)

1. 永恒的话题:内存泄漏

(1)动态申请堆空间用完后不归还

(2)C++语言中没有垃圾回收的机制

(3)指针无法控制所指堆空间生命周期

【编程实验】内存泄漏

#include <iostream>

#include "IntArray.h"

 

using namespace std;

 

class Test

{

    int i;

public:

    Test(int i)

    {

        this->i = i;

        cout << "Test(int i)" << endl;

    }

    int value(){return i;}

   

    ~Test()

    {

        cout << "~Test()" << endl;

    }

   

};

 

int main()

{

    for(int i = 0; i < 5; i++)

    {

        Test* p  = new Test(i);

       

        cout << p->value() << endl;

       

        //没有delete p造成内存泄漏

    }

   

    return 0;

}

 

2. 深度的思考:我们需要什么?

(1)需要一个特殊的指针,指针生命期结束主动释放堆空间

(2)一片堆空间最多只能由一个指针来标识

(3)杜绝指针运算指针比较因为只有一个该类对象的指针能指向堆空间

 

3. 解决方案

(1)重载指针特征操作符( -> 和 * )

(2)只能通过类的成员函数重载

(3)重载函数不能使用参数

(4)只能定义一个重载函数

(5)注意:智能指针只能用来指向堆空间中的对象或变量(不能指向栈)

【编程实验】智能指针

#include <iostream>

#include "IntArray.h"

 

using namespace std;

 

class Test

{

    int i;

public:

    Test(int i)

    {

        this->i = i;

        cout << "Test(int i)" << endl;

    }

    int value(){return i;}

   

    ~Test()

    {

        cout << "~Test()" << endl;

    }

   

};

 

//定义智能指针类

class Pointer

{

    Test* mp;//用于保存要被管理对象的指针

public:

    Pointer(Test* p = NULL)

    {

        mp = p;

    }

   

    Pointer(const Pointer& obj)

    {

        mp = obj.mp;

       

        //当Pointer p2 = p1时,p1所指的堆空间由p2来接管

        //即保证每次只能有一个智能指针指向同一堆空间

        const_cast<Pointer&>(obj).mp = NULL;

    }

   

    Pointer& operator = (const Pointer& obj)

    {

        if( this != &obj)

        {

            delete mp;

            mp = obj.mp;

            //保证赋值操作时,只能由一个智能指针指向同一堆空间

            const_cast<Pointer&>(obj).mp = NULL;

        }

    }

   

    //重载->操作符

    Test* operator ->() //不能使用参数,所以也就只能定义一个重载函数

    {

        return mp;

    }

   

    //重载*操作符

    Test& operator*()  //不能使用参数,所以也就只能定义一个重载函数

    {

        return *mp;

    }

   

    bool isNull()

    {

        return (mp == NULL);

    }

   

    ~Pointer()

    {

        delete mp;//智能指针被析构时,同时删除其所管理的Test类的对象

    }

};

 

int main()

{

    Pointer p1 = new Test(5);

   

    cout << p1->value() << endl;

   

    Pointer p2 = p1;//p2接管了p1所指的堆空间,保证每次只能由一个智能指针指向堆空间

   

    cout << p1.isNull() << endl;//p1指向NULL了,不再指向原来的堆空间

    cout << p2->value() << endl;//p2接管了p1所指堆空间

   

    //p2++;不重载++,因为每次只能一个智能指针指向堆空间,这种++操作没意义

   

    //p2智能指针生命期结束,会自动释放接管的堆空间

   

    return 0;

}

//输出结果:

//Test(int i)

//5

//1

//5

//~Test()

 

4. 小结

(1)指针特征操作符( -> 和 * )可以被重载

(2)重载指针特征符能够使用对象代替指针

(3)智能指针只能用于指向堆空间中的内存

(4)智能指针的意义在于最大程度避免内存问题

 

转载于:https://www.cnblogs.com/hoiday/p/10166424.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值