今天我们依然暂时不讲解数据结构里面的内容,我们来复习一下昨天学的模板技术用于数据结构编程的思想,给出一个模板技术的实例:智能指针的应用。喜欢看我分享的加我q:1126137994 加我共同学习交流各种技术。

为什么会引入智能指针呢?原因是在软件开发中最可恨最常见的BUG:内存泄漏!是什么导致内存泄漏?

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

那么引入智能指针后,智能指针能做什么呢?

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

智能指针的设计方案:
-通过类模板描述指针的行为
*能够定义不同类型的指针对象
-重载指针特征操作符(->和*)
*利用对象模拟原生指针的行为

重要说明:智能指针只能用来指向堆空间中的单个对象或者变量

下面给出代码示例,我主要做的是在QT编译器中建立了一个C++工程库,以后所有的数据结构的代码,都在这个库里实现:
头文件(SmartPointer.h):

#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H

namespace DTLib   
{

template <typename T>   //开始泛型编程
class SmartPointer     
{
protected:
    T* m_pointer;     //T类型指针

public:
    SmartPointer(T* p = NULL)
    {
        m_pointer = p;    //首先将m_pointer置空
    }
    SmartPointer(const SmartPointer<T>& obj) //拷贝构造函数,实现一片堆空间只能由一个指针标识
    {
        m_pointer = obj.m_pointer;
        const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
    }
    SmartPointer<T>& operator = (const SmartPointer<T>& obj)
    {
        if (this != &obj)   //判断是否自赋值,不能做比较运算,this当前的对象
        {
            delete m_pointer;
            m_pointer = obj.m_pointer;
            const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;

        }
        return *this;  //可以支持连续的赋值
    }

    T* operator-> ()   //重载->操作符,让T对象可以代表指针m_pointer
    {
        return m_pointer;
    }
    T& operator* ()    //重载*操作符,
    {
        return *m_pointer;
    }
    bool isNull()      //判断是否销毁指针
    {
        return (m_pointer == NULL);
    }
    T* get()        
    {
        return m_pointer;
    }
    ~SmartPointer()  //析构函数,很重要,对象的生命周期结束时主动的销毁指针
    {
        delete m_pointer;
    }

};

}

#endif // SMARTPOINTER_H

main.cpp函数:

#include <iostream>
#include "SmartPointer.h"

using namespace std;
using namespace DTLib;  //使用我们定义的命名空间

class Test
{
public:
    Test()     
    {
        cout << "Test()" << endl;   //测试试验,仅打印语句
    }
    ~Test()
    {
        cout << "~Test()" << endl;   //测试试验,仅打印语句
    }
};

int main()
{

    SmartPointer<Test> sp = new Test();   //声明一个智能指针sp指向Test对象所对应的的堆空间
    //SmartPointer<Test> nsp; //又定义了一个智能指针
    //nsp = sp; //该智能指针指向sp指向Test对象所对应的的堆空间


    //cout << sp.isNull() << endl;
    //cout << nsp.isNull() << endl;

    return 0;
}

运行上面程序,显示结果为:

可以看出,我们并没有主动去归还申请的堆空间,而是程序自动的调用了析构函数销毁了Test对象所对应的申请的堆空间。

那么我们将注释掉的那几行加上,编译运行:

可以看出,sp这个指针已经为空,nsp指针不为空,指向的是Test对象所对应的的堆空间,最后又将这个Test对象析构,销毁堆空间。
当然如果我们在main函数里加上一个nsp++的运算,编译就会报错,因为我们已经禁止了智能指针的比较与运算。

那么到此为此,我们已经实现了智能指针的实例。

总结:
1.指针特征操作符(->和*)可以被重载
2.重载指针特征符能够使用对象代替指针
3.智能指针只能用于指向堆空间中的指针
4.智能指针的意义在于最大程度的避免内存问题

想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题。