C++超详细讲解智能指针

一、内存泄漏-永恒的话题

  • 动态申请堆空间,用完后不归还
  • C++ 语言中没有垃圾回收的机制
  • 指针无法控制所指堆空间的生命周期

下面看一段内存泄漏的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

#include <iostream>

#include <string>

using namespace std;

class Test

{

    int i;

public:

    Test(int i)

    {

        this->i = i;

    }

    int value()

    {

        return i;

    }

    ~Test()

    {

    }

};

int main()

{

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

    {

        Test* p = new Test(i);       

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

    }   

    return 0;

}

输出结果如下:

二、深度思考

  • 需要一个特殊的指针
  • 指针生命周期结束时主动释放堆空间
  • 一片堆空间最多只能由一个指针标识
  • 杜绝指针运算和指针比较

三、智能指针分析

解决方案

  • 重载指针特征操作符( -> 和 * )
  • 只能通过类的成员函数重载
  • 重载函数不能使用参数
  • 只能定义一个重载函数

下面看一段智能指针的使用示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

#include <iostream>

#include <string>

using namespace std;

class Test

{

    int i;

public:

    Test(int i)

    {

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

        this->i = i;

    }

    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;

        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;

        }

        return *this;

    }

    Test* operator -> ()

    {

        return mp;

    }

    Test& operator * ()

    {

        return *mp;

    }

    bool isNull()

    {

        return (mp == NULL);

    }

    ~Pointer()

    {

        delete mp;

    }

};

int main()

{

    Pointer p1 = new Test(0);

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

    Pointer p2 = p1;

    cout << p1.isNull() << endl;

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

    return 0;

}

输出结果如下:

注意这两行代码的含义,

1

2

mp = obj.mp;

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

表明当前对象的成员指针指向初始化对象的成员指针所对应的堆空间,这就两个智能指针对象指向了同一片堆空间,然后 const_cast<Pointer&>(obj).mp = NULL; 表明初始化对象把自己管理的堆空间交给当前对象。这就完成了前面说的“一片堆空间最多只能由一个指针标识”。

茶狐在线提示:智能指针使用的军规:只能用来指向堆空间中的对象或者变量

四、小结

  • 指针特征操作符( -> 和 * )可以被重载
  • 重载指针特征符能够使用对象代替指针
  • 智能指针只能用于指向堆空间中的内存
  • 智能指针的意义在于最大程度的避免内存问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值