• 第37课 智能指针分析


    永恒的话题:

    内存泄漏示例:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Test
     7 {
     8     int i;
     9 public:
    10     Test(int i)
    11     {
    12         this->i = i;
    13     }
    14     int value()
    15     {
    16         return i;
    17     }
    18     ~Test()
    19     {
    20     }
    21 };
    22 
    23 int main()
    24 {
    25     for(int i=0; i<5; i++)
    26     {
    27         Test* p = new Test(i);
    28         
    29         cout << p->value() << endl;
    30         
    31     
    32     }
    33     
    34     return 0;
    35 }

    这段程序我们没有释放堆空间,造成了内存泄漏。

    深度的思考:

     一片堆空间最多只能由一个指针标识,这可以避免多次释放。杜绝指针运算和比较可以避免野指针。

    C++中不存在这样的指针,我们需要自己实现。

    解决方案:

    这四条都是硬性规定,最后两条说的是同一个问题。

    程序与运行结果如下:

    完善程序:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Test
     7 {
     8     int i;
     9 public:
    10     Test(int i)
    11     {
    12         cout << "Test(int i)" << endl;
    13         this->i = i;
    14     }
    15     int value()
    16     {
    17         return i;
    18     }
    19     ~Test()
    20     {
    21         cout << "~Test()" << endl;
    22     }
    23 };
    24 
    25 class Pointer
    26 {
    27     Test* mp;
    28 public:
    29     Pointer(Test* p = NULL)
    30     {
    31         mp = p;
    32     }
    33     Pointer(const Pointer& obj)
    34     {
    35         mp = obj.mp;
    36         const_cast<Pointer&>(obj).mp = NULL;
    37     }
    38     Pointer& operator = (const Pointer& obj)
    39     {
    40         if( this != &obj )
    41         {
    42             delete mp;
    43             mp = obj.mp;
    44             const_cast<Pointer&>(obj).mp = NULL;
    45         }
    46         
    47         return *this;
    48     }
    49     Test* operator -> ()
    50     {
    51         return mp;
    52     }
    53     Test& operator * ()
    54     {
    55         return *mp;
    56     }
    57     bool isNull()
    58     {
    59         return (mp == NULL);
    60     }
    61     ~Pointer()
    62     {
    63         delete mp;
    64     }
    65 };
    66 
    67 int main()
    68 {
    69     Pointer p1 = new Test(0);
    70     
    71     cout << p1->value() << endl;
    72     
    73     Pointer p2 = p1;
    74     
    75     cout << p1.isNull() << endl;
    76     
    77     cout << p2->value() << endl;
    78     
    79     return 0;
    80 }

    第49行重载的->和53行重载的*操作符没有参数,也没有重载,只定义一个,符合上面的最后两条要求。

     重载拷贝构造函数和赋值操作符,使得一个内存空间只能由一个智能指针指向。

    生成新对象才会调用拷贝构造函数,在拷贝构造函数中不能delete mp,因为这时候新生成的对象中mp还是野指针。

     上述程序运行结果如下:

    智能指针的使用军规:

    只能用来指向堆空间中的对象或者变量。

    小结:

  • 相关阅读:
    201671030116宋菲菲 实验三作业互评与改进报告
    通读《构建之法》提出问题
    201671010460-朱艺璇-实验四附加实验
    201671010460朱艺璇 词频统计软件项目报告
    201671010460朱艺璇 实验三作业互评与改进报告
    阅读《现代软件工程—构建之法》提出的问题
    手把手带你了解消息中间件(3)——RocketMQ
    字符编码的历史由来
    linux常用命令
    linux各目录及重要目录的详细介绍
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9573350.html
Copyright © 2020-2023  润新知