我们在程序开发中,难免会遇到内存泄漏。那么什么是内存泄漏呢?就是动态申请堆空间,用完后不归还。在 C++ 语言中没有垃圾回收机制,在后续的语言如 Java、C# 等高级语言中就存在垃圾回收机制,指针无法控制所指堆空间的生命周期。

        下来我们来看个示例代码

#include 
#include 
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;    }};int main(){    for(int i=0; i<5; i++)    {        Test* p = new Test(i);                cout << p->value() << endl;    }        return 0;}

        我们明显看到在 main 函数中只 new 对象了,而没有 delete 对象。我们看看运行结果

图片.png

        我们看到只是进行了构造函数,并没有析构函数的打印。也就是说,有内存泄漏,但是有人会说我们的程序还是运行结束了,啥事都没有。这是因为这个程序很短,如果程序在长时间运行后,便会产生问题,而且这类问题是最难调试的。

        那么我们就会思考了:我们到底需要的是一个什么样的指针的?需要一个特殊的指针,在指针生命周期结束时能主动释放堆空间一片堆空间最多只能由一个指针标识,必须杜绝指针运算和指针比较。那么解决方案便是重载指针特征操作符(-> 和 *),只能通过类的成员函数重载,并且重载函数不能使用参数它只能定义一个重载函数。我们称之为智能指针,下来我们来看看智能指针到底是什么样的

#include 
#include 
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
(obj).mp = NULL;    }    Pointer& operator = (const Pointer& obj)    {        if( this != &obj )        {            delete mp;            mp = obj.mp;            const_cast
(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(5);        cout << p1->value() << endl;        Pointer p2 = p1;        cout << p1.isNull() << endl;        cout << p2->value() << endl;        return 0;}

        我们在程序中定义了一个 Pointer 类,进行了一系列的操作符重载。打印 p1 的值就肯定为 5,接着将 p1 赋值给 p2,那么此时 p1 就应该为空了,因为一片空间只能有一个标识符。所以在第 78 行打印出的肯定是 1 了,最后打印的 p2 的值也就为 5 了。我们看看编译结果

图片.png

        我们看到打印的结果和我们所分析的是一致的,并且它也只是进行了一次构造函数和一次析构函数。那么关于智能指针这块,我们还有条使用军规:就是它只能用来指向堆空间中的对象或者变量!那么我们在 C++ 中的智能指针是不是就类似于高级语言中的垃圾回收机制呢?当然是很相似啦。通过对智能指针的学习,总结如下:1、指针特征操作符(-> 和 *)可以被重载;2、重载指针特征符能够使用对象代替指针;3、智能指针只能用于指向堆空间中的内存;4、智能指针的意义在于最大程度的避免内存问题。

        欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083