永恒的话题:

内存泄漏示例:

 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还是野指针。

 上述程序运行结果如下:

智能指针的使用军规:

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

 

小结:

 

posted on 2018-09-02 12:15  周伯通789  阅读(209)  评论(0编辑  收藏  举报